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
parent beee7a9d
......@@ -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;
......
......@@ -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.
......
......@@ -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
......@@ -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_
......@@ -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);
......
......@@ -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
};
......
......@@ -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
// 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
// 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_
......@@ -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,
......
......@@ -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
}
......
......@@ -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.
......
......@@ -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) {
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment