OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/performance_monitor/startup_timer.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/logging.h" |
| 9 #include "base/string_number_conversions.h" |
| 10 #include "chrome/browser/performance_monitor/database.h" |
| 11 #include "chrome/browser/performance_monitor/performance_monitor.h" |
| 12 #include "chrome/common/chrome_notification_types.h" |
| 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/notification_details.h" |
| 15 #include "content/public/browser/notification_service.h" |
| 16 #include "content/public/browser/notification_source.h" |
| 17 #include "content/public/browser/notification_types.h" |
| 18 |
| 19 namespace performance_monitor { |
| 20 |
| 21 namespace { |
| 22 // Needed because Database::AddMetric is overloaded, so base::Bind doesn't work. |
| 23 void AddMetricToDatabaseOnBackgroundThread(Database* database, |
| 24 MetricType metric, |
| 25 std::string value) { |
| 26 database->AddMetric(metric, value); |
| 27 } |
| 28 |
| 29 } // namespace |
| 30 |
| 31 // static |
| 32 StartupTimer* StartupTimer::g_startup_timer_ = NULL; |
| 33 |
| 34 StartupTimer::StartupTimer() : startup_begin_(base::TimeTicks::Now()), |
| 35 startup_type_(STARTUP_NORMAL), |
| 36 performance_monitor_initialized_(false) { |
| 37 CHECK(!g_startup_timer_); |
| 38 g_startup_timer_ = this; |
| 39 |
| 40 // We need this check because, under certain rare circumstances, |
| 41 // NotificationService::current() will return null, and this will cause a |
| 42 // segfault in NotificationServiceImpl::AddObserver(). Currently, this only |
| 43 // happens as a result of the child process launched by BrowserMainTest. |
| 44 // WarmConnectionFieldTrial_Invalid. |
| 45 if (content::NotificationService::current()) { |
| 46 registrar_.Add(this, chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED, |
| 47 content::NotificationService::AllSources()); |
| 48 } |
| 49 } |
| 50 |
| 51 StartupTimer::~StartupTimer() { |
| 52 DCHECK(this == g_startup_timer_); |
| 53 g_startup_timer_ = NULL; |
| 54 } |
| 55 |
| 56 bool StartupTimer::SignalStartupComplete(StartupType startup_type) { |
| 57 DCHECK(elapsed_startup_time_ == base::TimeDelta()); |
| 58 |
| 59 startup_type_ = startup_type; |
| 60 |
| 61 elapsed_startup_time_ = |
| 62 base::TimeTicks::Now() - total_pause_ - startup_begin_; |
| 63 |
| 64 if (performance_monitor_initialized_) |
| 65 InsertElapsedStartupTime(); |
| 66 |
| 67 return true; |
| 68 } |
| 69 |
| 70 // static |
| 71 void StartupTimer::PauseTimer() { |
| 72 // Check that the timer is not already paused. |
| 73 DCHECK(g_startup_timer_->pause_started_ == base::TimeTicks()); |
| 74 |
| 75 g_startup_timer_->pause_started_ = base::TimeTicks::Now(); |
| 76 } |
| 77 |
| 78 // static |
| 79 void StartupTimer::UnpauseTimer() { |
| 80 // Check that the timer has been paused. |
| 81 DCHECK(g_startup_timer_->pause_started_ != base::TimeTicks()); |
| 82 |
| 83 g_startup_timer_->total_pause_ += base::TimeTicks::Now() - |
| 84 g_startup_timer_->pause_started_; |
| 85 |
| 86 g_startup_timer_->pause_started_ = base::TimeTicks(); |
| 87 } |
| 88 |
| 89 void StartupTimer::Observe(int type, |
| 90 const content::NotificationSource& source, |
| 91 const content::NotificationDetails& details) { |
| 92 CHECK(type == chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED); |
| 93 performance_monitor_initialized_ = true; |
| 94 if (elapsed_startup_time_ != base::TimeDelta()) |
| 95 InsertElapsedStartupTime(); |
| 96 if (elapsed_session_restore_times_.size()) |
| 97 InsertElapsedSessionRestoreTime(); |
| 98 } |
| 99 |
| 100 // static |
| 101 void StartupTimer::SetElapsedSessionRestoreTime( |
| 102 const base::TimeDelta& elapsed_session_restore_time) { |
| 103 g_startup_timer_->elapsed_session_restore_times_.push_back( |
| 104 elapsed_session_restore_time); |
| 105 |
| 106 if (g_startup_timer_->performance_monitor_initialized_) |
| 107 g_startup_timer_->InsertElapsedSessionRestoreTime(); |
| 108 } |
| 109 |
| 110 void StartupTimer::InsertElapsedStartupTime() { |
| 111 content::BrowserThread::PostBlockingPoolSequencedTask( |
| 112 Database::kDatabaseSequenceToken, |
| 113 FROM_HERE, |
| 114 base::Bind( |
| 115 &AddMetricToDatabaseOnBackgroundThread, |
| 116 base::Unretained(PerformanceMonitor::GetInstance()->database()), |
| 117 startup_type_ == STARTUP_NORMAL ? METRIC_STARTUP_TIME |
| 118 : METRIC_TEST_STARTUP_TIME, |
| 119 base::Int64ToString(elapsed_startup_time_.ToInternalValue()))); |
| 120 } |
| 121 |
| 122 void StartupTimer::InsertElapsedSessionRestoreTime() { |
| 123 for (std::vector<base::TimeDelta>::const_iterator iter = |
| 124 elapsed_session_restore_times_.begin(); |
| 125 iter != elapsed_session_restore_times_.end(); ++iter) { |
| 126 content::BrowserThread::PostBlockingPoolSequencedTask( |
| 127 Database::kDatabaseSequenceToken, |
| 128 FROM_HERE, |
| 129 base::Bind( |
| 130 &AddMetricToDatabaseOnBackgroundThread, |
| 131 base::Unretained(PerformanceMonitor::GetInstance()->database()), |
| 132 METRIC_SESSION_RESTORE_TIME, |
| 133 base::Int64ToString(iter->ToInternalValue()))); |
| 134 } |
| 135 } |
| 136 |
| 137 } // namespace performance_monitor |
OLD | NEW |