diff options
author | rdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-09 20:30:24 +0000 |
---|---|---|
committer | rdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-09 20:30:24 +0000 |
commit | 0c1c47564b667a988d28e53fb7d276f20866796b (patch) | |
tree | 89daf84f415c95ce022ea36cbb0f07c8c1636483 /chrome | |
parent | beee7a9de8c1fb91f05ffa7eeb657a5679c1dfe4 (diff) | |
download | chromium_src-0c1c47564b667a988d28e53fb7d276f20866796b.zip chromium_src-0c1c47564b667a988d28e53fb7d276f20866796b.tar.gz chromium_src-0c1c47564b667a988d28e53fb7d276f20866796b.tar.bz2 |
Add Startup Timing to CPM
Add in support for timing chrome's startup and session restore times.
BUG=130212
TEST=Included
Review URL: https://chromiumcodereview.appspot.com/10834015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150881 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 11 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_main.h | 9 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/constants.cc | 21 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/constants.h | 17 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/metric_details.cc | 18 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/metric_details.h | 3 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/performance_monitor_browsertest.cc | 94 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/startup_timer.cc | 137 | ||||
-rw-r--r-- | chrome/browser/performance_monitor/startup_timer.h | 103 | ||||
-rw-r--r-- | chrome/browser/sessions/session_restore.cc | 3 | ||||
-rw-r--r-- | chrome/browser/sessions/session_restore_browsertest.cc | 7 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service.h | 1 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service_test_helper.cc | 6 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service_test_helper.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/startup/startup_browser_creator_impl.cc | 13 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
16 files changed, 439 insertions, 9 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 4b07ad4..d8eac6e 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -56,6 +56,7 @@ #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/notifications/desktop_notification_service_factory.h" #include "chrome/browser/page_cycler/page_cycler.h" +#include "chrome/browser/performance_monitor/startup_timer.h" #include "chrome/browser/plugin_prefs.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/pref_value_store.h" @@ -498,6 +499,7 @@ ChromeBrowserMainParts::ChromeBrowserMainParts( result_code_(content::RESULT_CODE_NORMAL_EXIT), startup_watcher_(new StartupTimeBomb()), shutdown_watcher_(new ShutdownWatcherHelper()), + startup_timer_(new performance_monitor::StartupTimer()), browser_field_trials_(parameters.command_line), record_search_engine_(false), translate_manager_(NULL), @@ -1383,6 +1385,10 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { PostBrowserStart(); if (parameters().ui_task) { + // We end the startup timer here if we have parameters to run, because we + // never start to run the main loop (where we normally stop the timer). + startup_timer_->SignalStartupComplete( + performance_monitor::StartupTimer::STARTUP_TEST); parameters().ui_task->Run(); delete parameters().ui_task; run_message_loop_ = false; @@ -1403,10 +1409,13 @@ bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) { if (!run_message_loop_) return true; // Don't run the default message loop. - // This should be invoked as close to the start of the browser's + // These should be invoked as close to the start of the browser's // UI thread message loop as possible to get a stable measurement // across versions. RecordBrowserStartupTime(); + startup_timer_->SignalStartupComplete( + performance_monitor::StartupTimer::STARTUP_NORMAL); + DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); #if !defined(USE_AURA) && defined(TOOLKIT_VIEWS) views::AcceleratorHandler accelerator_handler; diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h index 1b16d9c..c820c16 100644 --- a/chrome/browser/chrome_browser_main.h +++ b/chrome/browser/chrome_browser_main.h @@ -44,6 +44,10 @@ namespace content { struct MainFunctionParams; } +namespace performance_monitor { +class StartupTimer; +} + class ChromeBrowserMainParts : public content::BrowserMainParts { public: virtual ~ChromeBrowserMainParts(); @@ -132,6 +136,11 @@ class ChromeBrowserMainParts : public content::BrowserMainParts { // it is destroyed last. scoped_ptr<ShutdownWatcherHelper> shutdown_watcher_; + // A timer to hold data regarding startup and session restore times for + // PerformanceMonitor so that we don't have to start the entire + // PerformanceMonitor at browser startup. + scoped_ptr<performance_monitor::StartupTimer> startup_timer_; + // Creating this object starts tracking the creation and deletion of Task // instance. This MUST be done before main_message_loop, so that it is // destroyed after the main_message_loop. diff --git a/chrome/browser/performance_monitor/constants.cc b/chrome/browser/performance_monitor/constants.cc index 27d660b..3c167cc 100644 --- a/chrome/browser/performance_monitor/constants.cc +++ b/chrome/browser/performance_monitor/constants.cc @@ -53,4 +53,25 @@ const char kMetricSharedMemoryUsageDescription[] = const char kMetricSharedMemoryUsageUnits[] = "bytes"; const double kMetricSharedMemoryUsageTickSize = 10000000.0; +// Startup Time +const char kMetricStartupTimeName[] = "Startup Time"; +const char kMetricStartupTimeDescription[] = + "The startup time measured in microseconds"; +const char kMetricStartupTimeUnits[] = "microseconds"; +const double kMetricStartupTimeTickSize = 5000000; + +// Test Startup Time +const char kMetricTestStartupTimeName[] = "Test Startup Time"; +const char kMetricTestStartupTimeDescription[] = + "The startup time of test startups measured in microseconds"; +const char kMetricTestStartupTimeUnits[] = "microseconds"; +const double kMetricTestStartupTimeTickSize = 5000000; + +// Session Restore Time +const char kMetricSessionRestoreTimeName[] = "Session Restore Time"; +const char kMetricSessionRestoreTimeDescription[] = + "The session restore time measured in microseconds"; +const char kMetricSessionRestoreTimeUnits[] = "microseconds"; +const double kMetricSessionRestoreTimeTickSize = 5000000; + } // namespace performance_monitor diff --git a/chrome/browser/performance_monitor/constants.h b/chrome/browser/performance_monitor/constants.h index 9065538..dbf153d 100644 --- a/chrome/browser/performance_monitor/constants.h +++ b/chrome/browser/performance_monitor/constants.h @@ -24,15 +24,32 @@ extern const char kMetricCPUUsageName[]; extern const char kMetricCPUUsageDescription[]; extern const char kMetricCPUUsageUnits[]; extern const double kMetricCPUUsageTickSize; + extern const char kMetricPrivateMemoryUsageName[]; extern const char kMetricPrivateMemoryUsageDescription[]; extern const char kMetricPrivateMemoryUsageUnits[]; extern const double kMetricPrivateMemoryUsageTickSize; + extern const char kMetricSharedMemoryUsageName[]; extern const char kMetricSharedMemoryUsageDescription[]; extern const char kMetricSharedMemoryUsageUnits[]; extern const double kMetricSharedMemoryUsageTickSize; +extern const char kMetricStartupTimeName[]; +extern const char kMetricStartupTimeDescription[]; +extern const char kMetricStartupTimeUnits[]; +extern const double kMetricStartupTimeTickSize; + +extern const char kMetricTestStartupTimeName[]; +extern const char kMetricTestStartupTimeDescription[]; +extern const char kMetricTestStartupTimeUnits[]; +extern const double kMetricTestStartupTimeTickSize; + +extern const char kMetricSessionRestoreTimeName[]; +extern const char kMetricSessionRestoreTimeDescription[]; +extern const char kMetricSessionRestoreTimeUnits[]; +extern const double kMetricSessionRestoreTimeTickSize; + } // namespace performance_monitor #endif // CHROME_BROWSER_PERFORMANCE_MONITOR_CONSTANTS_H_ diff --git a/chrome/browser/performance_monitor/metric_details.cc b/chrome/browser/performance_monitor/metric_details.cc index 2767728..613bfdf 100644 --- a/chrome/browser/performance_monitor/metric_details.cc +++ b/chrome/browser/performance_monitor/metric_details.cc @@ -31,6 +31,24 @@ const MetricDetails kMetricDetailsList[] = { kMetricSharedMemoryUsageUnits, kMetricSharedMemoryUsageTickSize }, + { + kMetricStartupTimeName, + kMetricStartupTimeDescription, + kMetricStartupTimeUnits, + kMetricStartupTimeTickSize + }, + { + kMetricTestStartupTimeName, + kMetricTestStartupTimeDescription, + kMetricTestStartupTimeUnits, + kMetricTestStartupTimeTickSize + }, + { + kMetricSessionRestoreTimeName, + kMetricSessionRestoreTimeDescription, + kMetricSessionRestoreTimeUnits, + kMetricSessionRestoreTimeTickSize + } }; COMPILE_ASSERT(ARRAYSIZE_UNSAFE(kMetricDetailsList) == METRIC_NUMBER_OF_METRICS, metric_names_incorrect_size); diff --git a/chrome/browser/performance_monitor/metric_details.h b/chrome/browser/performance_monitor/metric_details.h index 10f1ff0..ba0f357 100644 --- a/chrome/browser/performance_monitor/metric_details.h +++ b/chrome/browser/performance_monitor/metric_details.h @@ -14,6 +14,9 @@ enum MetricType { METRIC_CPU_USAGE, METRIC_PRIVATE_MEMORY_USAGE, METRIC_SHARED_MEMORY_USAGE, + METRIC_STARTUP_TIME, + METRIC_TEST_STARTUP_TIME, + METRIC_SESSION_RESTORE_TIME, METRIC_NUMBER_OF_METRICS }; diff --git a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc index abbb4b6..acc5612 100644 --- a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc +++ b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc @@ -11,17 +11,25 @@ #include "base/string_number_conversions.h" #include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/performance_monitor/constants.h" -#include "chrome/browser/performance_monitor/database.h" -#include "chrome/browser/performance_monitor/performance_monitor.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/unpacked_installer.h" +#include "chrome/browser/performance_monitor/constants.h" +#include "chrome/browser/performance_monitor/database.h" +#include "chrome/browser/performance_monitor/performance_monitor.h" +#include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/sessions/session_restore.h" +#include "chrome/browser/sessions/session_service.h" +#include "chrome/browser/sessions/session_service_test_helper.h" +#include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_notification_types.h" @@ -35,13 +43,20 @@ #include "content/public/browser/notification_service.h" #include "content/public/common/page_transition_types.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" +#if defined(OS_MACOSX) +#include "base/mac/scoped_nsautorelease_pool.h" +#endif + using extensions::Extension; using performance_monitor::Event; namespace { +const base::TimeDelta kMaxStartupTime = base::TimeDelta::FromMinutes(3); + // Helper struct to store the information of an extension; this is needed if the // pointer to the extension ever becomes invalid (e.g., if we uninstall the // extension). @@ -305,6 +320,54 @@ class PerformanceMonitorUncleanExitBrowserTest std::string second_profile_name_; }; +class PerformanceMonitorSessionRestoreBrowserTest + : public PerformanceMonitorBrowserTest { + public: + virtual void SetUpOnMainThread() OVERRIDE { + SessionStartupPref pref(SessionStartupPref::LAST); + SessionStartupPref::SetStartupPref(browser()->profile(), pref); +#if defined(OS_CHROMEOS) || defined (OS_MACOSX) + // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we + // can get these test to work without quitting. + SessionServiceTestHelper helper( + SessionServiceFactory::GetForProfile(browser()->profile())); + helper.SetForceBrowserNotAliveWithNoWindows(true); + helper.ReleaseService(); +#endif + + PerformanceMonitorBrowserTest::SetUpOnMainThread(); + } + + Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) { + Profile* profile = browser->profile(); + + // Close the browser. + g_browser_process->AddRefModule(); + content::WindowedNotificationObserver observer( + chrome::NOTIFICATION_BROWSER_CLOSED, + content::NotificationService::AllSources()); + browser->window()->Close(); +#if defined(OS_MACOSX) + // BrowserWindowController depends on the auto release pool being recycled + // in the message loop to delete itself, which frees the Browser object + // which fires this event. + AutoreleasePool()->Recycle(); +#endif + observer.Wait(); + + // Create a new window, which should trigger session restore. + ui_test_utils::BrowserAddedObserver window_observer; + content::TestNavigationObserver navigation_observer( + content::NotificationService::AllSources(), NULL, expected_tab_count); + chrome::NewEmptyWindow(profile); + Browser* new_browser = window_observer.WaitForSingleNewBrowser(); + navigation_observer.Wait(); + g_browser_process->ReleaseModule(); + + return new_browser; + } +}; + // Test that PerformanceMonitor will correctly record an extension installation // event. IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, InstallExtensionEvent) { @@ -631,4 +694,29 @@ IN_PROC_BROWSER_TEST_F(PerformanceMonitorUncleanExitBrowserTest, ASSERT_EQ(second_profile_name_, event_profile); } +IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, StartupTime) { + Database::MetricInfoVector metrics = GetStats(METRIC_TEST_STARTUP_TIME); + + ASSERT_EQ(1u, metrics.size()); + ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue()); +} + +IN_PROC_BROWSER_TEST_F(PerformanceMonitorSessionRestoreBrowserTest, + StartupWithSessionRestore) { + ui_test_utils::NavigateToURL( + browser(), + ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory), + FilePath(FILE_PATH_LITERAL("title1.html")))); + + QuitBrowserAndRestore(browser(), 1); + + Database::MetricInfoVector metrics = GetStats(METRIC_TEST_STARTUP_TIME); + ASSERT_EQ(1u, metrics.size()); + ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue()); + + metrics = GetStats(METRIC_SESSION_RESTORE_TIME); + ASSERT_EQ(1u, metrics.size()); + ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue()); +} + } // namespace performance_monitor diff --git a/chrome/browser/performance_monitor/startup_timer.cc b/chrome/browser/performance_monitor/startup_timer.cc new file mode 100644 index 0000000..0af0a57 --- /dev/null +++ b/chrome/browser/performance_monitor/startup_timer.cc @@ -0,0 +1,137 @@ +// Copyright (c) 2012 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/performance_monitor/startup_timer.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "chrome/browser/performance_monitor/database.h" +#include "chrome/browser/performance_monitor/performance_monitor.h" +#include "chrome/common/chrome_notification_types.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" + +namespace performance_monitor { + +namespace { +// Needed because Database::AddMetric is overloaded, so base::Bind doesn't work. +void AddMetricToDatabaseOnBackgroundThread(Database* database, + MetricType metric, + std::string value) { + database->AddMetric(metric, value); +} + +} // namespace + +// static +StartupTimer* StartupTimer::g_startup_timer_ = NULL; + +StartupTimer::StartupTimer() : startup_begin_(base::TimeTicks::Now()), + startup_type_(STARTUP_NORMAL), + performance_monitor_initialized_(false) { + CHECK(!g_startup_timer_); + g_startup_timer_ = this; + + // We need this check because, under certain rare circumstances, + // NotificationService::current() will return null, and this will cause a + // segfault in NotificationServiceImpl::AddObserver(). Currently, this only + // happens as a result of the child process launched by BrowserMainTest. + // WarmConnectionFieldTrial_Invalid. + if (content::NotificationService::current()) { + registrar_.Add(this, chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED, + content::NotificationService::AllSources()); + } +} + +StartupTimer::~StartupTimer() { + DCHECK(this == g_startup_timer_); + g_startup_timer_ = NULL; +} + +bool StartupTimer::SignalStartupComplete(StartupType startup_type) { + DCHECK(elapsed_startup_time_ == base::TimeDelta()); + + startup_type_ = startup_type; + + elapsed_startup_time_ = + base::TimeTicks::Now() - total_pause_ - startup_begin_; + + if (performance_monitor_initialized_) + InsertElapsedStartupTime(); + + return true; +} + +// static +void StartupTimer::PauseTimer() { + // Check that the timer is not already paused. + DCHECK(g_startup_timer_->pause_started_ == base::TimeTicks()); + + g_startup_timer_->pause_started_ = base::TimeTicks::Now(); +} + +// static +void StartupTimer::UnpauseTimer() { + // Check that the timer has been paused. + DCHECK(g_startup_timer_->pause_started_ != base::TimeTicks()); + + g_startup_timer_->total_pause_ += base::TimeTicks::Now() - + g_startup_timer_->pause_started_; + + g_startup_timer_->pause_started_ = base::TimeTicks(); +} + +void StartupTimer::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + CHECK(type == chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED); + performance_monitor_initialized_ = true; + if (elapsed_startup_time_ != base::TimeDelta()) + InsertElapsedStartupTime(); + if (elapsed_session_restore_times_.size()) + InsertElapsedSessionRestoreTime(); +} + +// static +void StartupTimer::SetElapsedSessionRestoreTime( + const base::TimeDelta& elapsed_session_restore_time) { + g_startup_timer_->elapsed_session_restore_times_.push_back( + elapsed_session_restore_time); + + if (g_startup_timer_->performance_monitor_initialized_) + g_startup_timer_->InsertElapsedSessionRestoreTime(); +} + +void StartupTimer::InsertElapsedStartupTime() { + content::BrowserThread::PostBlockingPoolSequencedTask( + Database::kDatabaseSequenceToken, + FROM_HERE, + base::Bind( + &AddMetricToDatabaseOnBackgroundThread, + base::Unretained(PerformanceMonitor::GetInstance()->database()), + startup_type_ == STARTUP_NORMAL ? METRIC_STARTUP_TIME + : METRIC_TEST_STARTUP_TIME, + base::Int64ToString(elapsed_startup_time_.ToInternalValue()))); +} + +void StartupTimer::InsertElapsedSessionRestoreTime() { + for (std::vector<base::TimeDelta>::const_iterator iter = + elapsed_session_restore_times_.begin(); + iter != elapsed_session_restore_times_.end(); ++iter) { + content::BrowserThread::PostBlockingPoolSequencedTask( + Database::kDatabaseSequenceToken, + FROM_HERE, + base::Bind( + &AddMetricToDatabaseOnBackgroundThread, + base::Unretained(PerformanceMonitor::GetInstance()->database()), + METRIC_SESSION_RESTORE_TIME, + base::Int64ToString(iter->ToInternalValue()))); + } +} + +} // namespace performance_monitor diff --git a/chrome/browser/performance_monitor/startup_timer.h b/chrome/browser/performance_monitor/startup_timer.h new file mode 100644 index 0000000..2bab4db --- /dev/null +++ b/chrome/browser/performance_monitor/startup_timer.h @@ -0,0 +1,103 @@ +// Copyright (c) 2012 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_PERFORMANCE_MONITOR_STARTUP_TIMER_H_ +#define CHROME_BROWSER_PERFORMANCE_MONITOR_STARTUP_TIMER_H_ + +#include "base/time.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +namespace performance_monitor { + +// This class is responsible for recording the startup and session restore times +// (if applicable) for PerformanceMonitor. This allows us to initialize this +// relatively small object early in the startup process, and start the whole of +// PerformanceMonitor at a later time. StartupTimer will record the times and +// insert them into PerformanceMonitor's database. +class StartupTimer : public content::NotificationObserver { + public: + // Indicates the type of startup; i.e. either a normal startup or a testing + // environment. + enum StartupType { + STARTUP_NORMAL, + STARTUP_TEST + }; + + StartupTimer(); + virtual ~StartupTimer(); + + // Inform StartupTimer that the startup process has been completed; stop the + // timer. Returns false if the timer has already stopped. + bool SignalStartupComplete(StartupType startup_type); + + // Pauses the timer until UnpauseTimer() is called; any time spent within a + // pause does not count towards the measured startup time. This will DCHECK if + // PauseTimer() is called while paused or UnpauseTimer() is called while + // unpaused. + static void PauseTimer(); + static void UnpauseTimer(); + + // content::NotificationObserver + // We keep track of whether or not PerformanceMonitor has been started via + // the PERFORMANCE_MONITOR_INITIALIZED notification; we need to know this so + // we know when to insert startup data into the database. We either insert + // data as we gather it (if PerformanceMonitor is started prior to data + // collection) or at the notification (if PerformanceMonitor is started + // later). + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + static void SetElapsedSessionRestoreTime( + const base::TimeDelta& elapsed_session_restore_time); + + private: + // Insert the elapsed time measures into PerformanceMonitor's database. + void InsertElapsedStartupTime(); + void InsertElapsedSessionRestoreTime(); + + // The time at which the startup process begins (the creation of + // ChromeBrowserMain). + base::TimeTicks startup_begin_; + + // The time at which the timer was most recently paused, or null if the timer + // is not currently paused. + base::TimeTicks pause_started_; + + // The total duration for which the timer has been paused. + base::TimeDelta total_pause_; + + // A flag of whether or not this was a "normal" startup (e.g. whether or not + // this was in a testing environment, which would change the startup time + // values). If it is not a normal startup, we use a different metric. + StartupType startup_type_; + + // The total duration of the startup process, minus any pauses. + base::TimeDelta elapsed_startup_time_; + + // The total duration of the session restore(s), if any occurred. This is + // independent of the startup time, because: + // - If the user has auto-restore on, the restore is synchronous, and we pause + // the startup timer during the session restore; the restore will not + // interfere with startup timing. + // - If Chrome crashed and the user chooses to restore the crashed session, + // then the startup is already completed; the restore will not interfere + // with startup timing. + std::vector<base::TimeDelta> elapsed_session_restore_times_; + + // Flag whether or not PerformanceMonitor has been fully started. + bool performance_monitor_initialized_; + + content::NotificationRegistrar registrar_; + + // The singleton of this class. + static StartupTimer* g_startup_timer_; + + DISALLOW_COPY_AND_ASSIGN(StartupTimer); +}; + +} // namespace performance_monitor + +#endif // CHROME_BROWSER_PERFORMANCE_MONITOR_STARTUP_TIMER_H_ diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index 7351544..2906eec 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc @@ -20,6 +20,7 @@ #include "base/stringprintf.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/performance_monitor/startup_timer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" @@ -440,6 +441,8 @@ void TabLoader::HandleTabClosedOrLoaded(NavigationController* tab) { if (tabs_loading_.empty() && tabs_to_load_.empty()) { base::TimeDelta time_to_load = base::TimeTicks::Now() - restore_started_; + performance_monitor::StartupTimer::SetElapsedSessionRestoreTime( + time_to_load); UMA_HISTOGRAM_CUSTOM_TIMES( "SessionRestore.AllTabsLoaded", time_to_load, diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 154bf0a..9155f82 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" +#include "chrome/browser/sessions/session_service_test_helper.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/ui/browser.h" @@ -51,8 +52,10 @@ class SessionRestoreTest : public InProcessBrowserTest { if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS")) { // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we // can get these test to work without quitting. - SessionServiceFactory::GetForProfile(browser()->profile())-> - force_browser_not_alive_with_no_windows_ = true; + SessionServiceTestHelper helper( + SessionServiceFactory::GetForProfile(browser()->profile())); + helper.SetForceBrowserNotAliveWithNoWindows(true); + helper.ReleaseService(); } #endif } diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h index 97621cf..f40ad3a 100644 --- a/chrome/browser/sessions/session_service.h +++ b/chrome/browser/sessions/session_service.h @@ -52,7 +52,6 @@ class NavigationEntry; // of the browser. class SessionService : public BaseSessionService, public content::NotificationObserver { - friend class SessionRestoreTest; friend class SessionServiceTestHelper; public: // Used to distinguish an application window from a normal one. diff --git a/chrome/browser/sessions/session_service_test_helper.cc b/chrome/browser/sessions/session_service_test_helper.cc index 2953e02..3f02a4c 100644 --- a/chrome/browser/sessions/session_service_test_helper.cc +++ b/chrome/browser/sessions/session_service_test_helper.cc @@ -50,6 +50,12 @@ void SessionServiceTestHelper::SetTabUserAgentOverride( service()->SetTabUserAgentOverride(window_id, tab_id, user_agent_override); } +void SessionServiceTestHelper::SetForceBrowserNotAliveWithNoWindows( + bool force_browser_not_alive_with_no_windows) { + service()->force_browser_not_alive_with_no_windows_ = + force_browser_not_alive_with_no_windows; +} + // Be sure and null out service to force closing the file. void SessionServiceTestHelper::ReadWindows( std::vector<SessionWindow*>* windows) { diff --git a/chrome/browser/sessions/session_service_test_helper.h b/chrome/browser/sessions/session_service_test_helper.h index 3419712..cccb1d3 100644 --- a/chrome/browser/sessions/session_service_test_helper.h +++ b/chrome/browser/sessions/session_service_test_helper.h @@ -43,6 +43,9 @@ class SessionServiceTestHelper { const SessionID& tab_id, const std::string& user_agent_override); + void SetForceBrowserNotAliveWithNoWindows( + bool force_browser_not_alive_with_no_windows); + // Reads the contents of the last session. void ReadWindows(std::vector<SessionWindow*>* windows); diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index adcb2f3..4bb4994 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc @@ -29,6 +29,7 @@ #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/notifications/desktop_notification_service.h" +#include "chrome/browser/performance_monitor/startup_timer.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -606,8 +607,8 @@ bool StartupBrowserCreatorImpl::ProcessStartupURLs( return false; } - uint32 restore_behavior = SessionRestore::SYNCHRONOUS | - SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; + uint32 restore_behavior = SessionRestore::SYNCHRONOUS | + SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; #if defined(OS_MACOSX) // On Mac, when restoring a session with no windows, suppress the creation // of a new window in the case where the system is launching Chrome via a @@ -618,10 +619,18 @@ bool StartupBrowserCreatorImpl::ProcessStartupURLs( } #endif + // Pause the StartupTimer. Since the restore here is synchronous, we can + // keep these two metrics (browser startup time and session restore time) + // separate. + performance_monitor::StartupTimer::PauseTimer(); + Browser* browser = SessionRestore::RestoreSession(profile_, NULL, restore_behavior, urls_to_open); + + performance_monitor::StartupTimer::UnpauseTimer(); + AddInfoBarsIfNecessary(browser, chrome::startup::IS_PROCESS_STARTUP); return true; } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 69a83a2..312608a 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1648,6 +1648,8 @@ 'browser/performance_monitor/performance_monitor.h', 'browser/performance_monitor/performance_monitor_util.cc', 'browser/performance_monitor/performance_monitor_util.h', + 'browser/performance_monitor/startup_timer.cc', + 'browser/performance_monitor/startup_timer.h', 'browser/platform_util.h', 'browser/platform_util_android.cc', 'browser/platform_util_aura.cc', |