1 // Copyright 2014 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.
5 #if !defined(OS_ANDROID)
7 #include "chrome/browser/metrics/first_web_contents_profiler.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "base/process/process_info.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_iterator.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/chrome_version_info.h"
19 const int kHistogramMinTimeMilliseconds
= 200;
20 const int kHistogramMaxTimeSeconds
= 45;
22 // There is a lot of noise in the dev channel. One possible cause is that the
23 // bucket ranges are too wide. The bucket count is chosen such that the size of
24 // the bucket is 1% of its minimum. Notice that this also means that
25 // subsequent buckets will satisfy Min(bucket N + 1) / Min(bucket N) = 1.01.
26 // Then we want X, such that 1.01 ^ X = 45 * 1000 / 200. Some quick math shows
28 const int kHistogramBucketCount
= 544;
32 scoped_ptr
<FirstWebContentsProfiler
>
33 FirstWebContentsProfiler::CreateProfilerForFirstWebContents(
36 for (chrome::BrowserIterator iterator
; !iterator
.done(); iterator
.Next()) {
37 Browser
* browser
= *iterator
;
38 content::WebContents
* web_contents
=
39 browser
->tab_strip_model()->GetActiveWebContents();
41 return scoped_ptr
<FirstWebContentsProfiler
>(
42 new FirstWebContentsProfiler(web_contents
, delegate
));
48 bool FirstWebContentsProfiler::ShouldCollectMetrics() {
49 chrome::VersionInfo::Channel channel
= chrome::VersionInfo::GetChannel();
50 return channel
== chrome::VersionInfo::CHANNEL_CANARY
||
51 channel
== chrome::VersionInfo::CHANNEL_DEV
;
54 FirstWebContentsProfiler::FirstWebContentsProfiler(
55 content::WebContents
* web_contents
,
57 : content::WebContentsObserver(web_contents
),
58 collected_paint_metric_(false),
59 collected_load_metric_(false),
61 process_creation_time_
= base::CurrentProcessInfo::CreationTime();
64 void FirstWebContentsProfiler::DidFirstVisuallyNonEmptyPaint() {
65 if (collected_paint_metric_
)
68 collected_paint_metric_
= true;
69 if (!process_creation_time_
.is_null()) {
70 base::TimeDelta elapsed
= base::Time::Now() - process_creation_time_
;
72 // TODO(erikchen): Revisit these metrics once data has been collected to
73 // determine whether using more buckets reduces noise and provides higher
74 // quality information.
75 UMA_HISTOGRAM_CUSTOM_TIMES(
76 "Startup.Experimental.FirstWebContents.NonEmptyPaint."
79 base::TimeDelta::FromMilliseconds(kHistogramMinTimeMilliseconds
),
80 base::TimeDelta::FromSeconds(kHistogramMaxTimeSeconds
),
81 kHistogramBucketCount
);
82 UMA_HISTOGRAM_LONG_TIMES_100(
83 "Startup.Experimental.FirstWebContents.NonEmptyPaint.StandardBuckets",
87 if (IsFinishedCollectingMetrics())
88 FinishedCollectingMetrics();
91 void FirstWebContentsProfiler::DocumentOnLoadCompletedInMainFrame() {
92 if (collected_load_metric_
)
95 collected_load_metric_
= true;
96 if (!process_creation_time_
.is_null()) {
97 base::TimeDelta elapsed
= base::Time::Now() - process_creation_time_
;
99 // TODO(erikchen): Revisit these metrics once data has been collected to
100 // determine whether using more buckets reduces noise and provides higher
101 // quality information.
102 UMA_HISTOGRAM_CUSTOM_TIMES(
103 "Startup.Experimental.FirstWebContents.MainFrameLoad."
106 base::TimeDelta::FromMilliseconds(kHistogramMinTimeMilliseconds
),
107 base::TimeDelta::FromSeconds(kHistogramMaxTimeSeconds
),
108 kHistogramBucketCount
);
109 UMA_HISTOGRAM_LONG_TIMES_100(
110 "Startup.Experimental.FirstWebContents.MainFrameLoad.StandardBuckets",
114 if (IsFinishedCollectingMetrics())
115 FinishedCollectingMetrics();
118 void FirstWebContentsProfiler::WebContentsDestroyed() {
119 FinishedCollectingMetrics();
122 bool FirstWebContentsProfiler::IsFinishedCollectingMetrics() {
123 return collected_paint_metric_
&& collected_load_metric_
;
126 void FirstWebContentsProfiler::FinishedCollectingMetrics() {
127 delegate_
->ProfilerFinishedCollectingMetrics();
130 #endif // !defined(OS_ANDROID)