Chromium Code Reviews| Index: chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc |
| diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc |
| index 5ca78d2c878dadfd35ef372b82e66b50e6ab46ac..a8d9c23d1e0bd8cac554b3d6861e43cec51c4cd5 100644 |
| --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc |
| +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc |
| @@ -11,6 +11,7 @@ |
| #include "base/cpu.h" |
| #include "base/metrics/histogram.h" |
| #include "base/metrics/sparse_histogram.h" |
| +#include "base/process/process_info.h" |
| #include "base/sys_info.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "base/time/time.h" |
| @@ -20,7 +21,11 @@ |
| #include "chrome/browser/mac/bluetooth_utility.h" |
| #include "chrome/browser/pref_service_flags_storage.h" |
| #include "chrome/browser/shell_integration.h" |
| +#include "chrome/browser/ui/browser.h" |
| +#include "chrome/browser/ui/browser_iterator.h" |
| +#include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/web_contents_observer.h" |
| #include "ui/base/touch/touch_device.h" |
| #include "ui/base/ui_base_switches.h" |
| #include "ui/events/event_switches.h" |
| @@ -222,6 +227,76 @@ void RecordTouchEventState() { |
| } // namespace |
| +// Measures start up performance of the first active web contents. |
| +class ChromeBrowserMainExtraPartsMetrics::FirstWebContentsProfiler |
| + : public content::WebContentsObserver { |
| + public: |
| + FirstWebContentsProfiler(content::WebContents* web_contents, |
| + ChromeBrowserMainExtraPartsMetrics* metrics) |
| + : content::WebContentsObserver(web_contents), |
| + recorded_paint_metric_(false), |
| + recorded_load_metric_(false), |
| + metrics_(metrics) {} |
| + |
| + private: |
| + void DidFirstVisuallyNonEmptyPaint() override { |
| + if (recorded_paint_metric_) |
| + return; |
| + recorded_paint_metric_ = true; |
| + const base::Time process_creation_time = |
| + base::CurrentProcessInfo::CreationTime(); |
| + if (!process_creation_time.is_null()) { |
| + base::TimeDelta elapsed = base::Time::Now() - process_creation_time; |
| + UMA_HISTOGRAM_CUSTOM_TIMES("Startup.FirstWebContents.NonEmptyPaint", |
| + elapsed, |
| + base::TimeDelta::FromMilliseconds(100), |
| + base::TimeDelta::FromMinutes(2), 300); |
|
Ilya Sherman
2014/11/26 02:24:55
Could you clarify why you need such fine granulari
erikchen
2014/11/26 03:48:43
I am basing these numbers on the histograms Startu
|
| + } |
| + |
| + if (FinishedRecordingMetrics()) |
| + DestroySelf(); |
| + } |
| + |
| + void DocumentOnLoadCompletedInMainFrame() override { |
| + if (recorded_load_metric_) |
| + return; |
| + recorded_load_metric_ = true; |
| + const base::Time process_creation_time = |
| + base::CurrentProcessInfo::CreationTime(); |
| + if (!process_creation_time.is_null()) { |
| + base::TimeDelta elapsed = base::Time::Now() - process_creation_time; |
| + UMA_HISTOGRAM_CUSTOM_TIMES("Startup.FirstWebContents.MainFrameLoad", |
| + elapsed, |
| + base::TimeDelta::FromMilliseconds(100), |
| + base::TimeDelta::FromMinutes(2), 300); |
| + } |
| + |
| + if (FinishedRecordingMetrics()) |
| + DestroySelf(); |
| + } |
| + |
| + void WebContentsDestroyed() override { DestroySelf(); } |
| + |
| + // Whether all metrics have been recorded. |
| + bool FinishedRecordingMetrics() { |
| + return recorded_paint_metric_ && recorded_load_metric_; |
| + } |
| + |
| + // Tells the owner of |this| to destroy |this|. |
| + void DestroySelf() { metrics_->FirstWebContentsProfilerWantsDestruction(); } |
| + |
| + // Whether the "NonEmptyPaint" metric has been recorded. |
| + bool recorded_paint_metric_; |
| + |
| + // Whether the "MainFrameLoad" metric has been recorded. |
| + bool recorded_load_metric_; |
| + |
| + // |metrics_| owns |this|. |
| + ChromeBrowserMainExtraPartsMetrics* metrics_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FirstWebContentsProfiler); |
| +}; |
|
Ilya Sherman
2014/11/26 02:24:55
Please split this class out into its own implement
erikchen
2014/11/26 03:48:43
I split out the file into its own implementation.
|
| + |
| ChromeBrowserMainExtraPartsMetrics::ChromeBrowserMainExtraPartsMetrics() |
| : display_count_(0), is_screen_observer_(false) { |
| } |
| @@ -264,6 +339,19 @@ void ChromeBrowserMainExtraPartsMetrics::PostBrowserStart() { |
| UMA_HISTOGRAM_COUNTS_100("Hardware.Display.Count.OnStartup", display_count_); |
| gfx::Screen::GetNativeScreen()->AddObserver(this); |
| is_screen_observer_ = true; |
| + |
| + // Record startup metrics for the active web contents. If there are multiple |
| + // browsers, choose the first one. |
| + for (chrome::BrowserIterator iterator; !iterator.done(); iterator.Next()) { |
| + Browser* browser = *iterator; |
| + content::WebContents* web_contents = |
| + browser->tab_strip_model()->GetActiveWebContents(); |
| + if (web_contents) { |
| + first_web_contents_profiler_.reset( |
| + new FirstWebContentsProfiler(web_contents, this)); |
| + break; |
| + } |
| + } |
|
Ilya Sherman
2014/11/26 02:24:55
I think this logic could safely be internal to the
erikchen
2014/11/26 03:48:43
Done.
|
| } |
| void ChromeBrowserMainExtraPartsMetrics::OnDisplayAdded( |
| @@ -289,6 +377,11 @@ void ChromeBrowserMainExtraPartsMetrics::EmitDisplaysChangedMetric() { |
| } |
| } |
| +void ChromeBrowserMainExtraPartsMetrics:: |
| + FirstWebContentsProfilerWantsDestruction() { |
| + first_web_contents_profiler_.reset(); |
| +} |
| + |
| namespace chrome { |
| void AddMetricsExtraParts(ChromeBrowserMainParts* main_parts) { |