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) { |