OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" | 5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "components/page_load_metrics/common/page_load_metrics_messages.h" | 9 #include "components/page_load_metrics/common/page_load_metrics_messages.h" |
10 #include "components/page_load_metrics/common/page_load_timing.h" | 10 #include "components/page_load_metrics/common/page_load_timing.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 } | 57 } |
58 | 58 |
59 } // namespace | 59 } // namespace |
60 | 60 |
61 #define PAGE_LOAD_HISTOGRAM(name, sample) \ | 61 #define PAGE_LOAD_HISTOGRAM(name, sample) \ |
62 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ | 62 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ |
63 base::TimeDelta::FromMilliseconds(10), \ | 63 base::TimeDelta::FromMilliseconds(10), \ |
64 base::TimeDelta::FromMinutes(10), 100) | 64 base::TimeDelta::FromMinutes(10), 100) |
65 | 65 |
66 PageLoadTracker::PageLoadTracker(bool in_foreground) | 66 PageLoadTracker::PageLoadTracker(bool in_foreground) |
67 : has_commit_(false), started_in_foreground_(in_foreground) {} | 67 : has_commit_(false), started_in_foreground_(in_foreground) { |
| 68 RecordEvent(PAGE_LOAD_STARTED); |
| 69 } |
68 | 70 |
69 PageLoadTracker::~PageLoadTracker() { | 71 PageLoadTracker::~PageLoadTracker() { |
| 72 // Even a load that failed a provisional load should log |
| 73 // that it aborted before first layout. |
| 74 if (timing_.first_layout.is_zero()) |
| 75 RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); |
| 76 |
70 if (has_commit_) | 77 if (has_commit_) |
71 RecordTimingHistograms(); | 78 RecordTimingHistograms(); |
72 } | 79 } |
73 | 80 |
74 void PageLoadTracker::WebContentsHidden() { | 81 void PageLoadTracker::WebContentsHidden() { |
75 // Only log the first time we background in a given page load. | 82 // Only log the first time we background in a given page load. |
76 if (background_time_.is_null()) { | 83 if (background_time_.is_null()) { |
77 background_time_ = base::TimeTicks::Now(); | 84 background_time_ = base::TimeTicks::Now(); |
78 } | 85 } |
79 } | 86 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 timing_.load_event_start); | 132 timing_.load_event_start); |
126 } else { | 133 } else { |
127 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", | 134 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", |
128 timing_.load_event_start); | 135 timing_.load_event_start); |
129 } | 136 } |
130 } | 137 } |
131 if (!timing_.first_layout.is_zero()) { | 138 if (!timing_.first_layout.is_zero()) { |
132 if (timing_.first_layout < background_delta) { | 139 if (timing_.first_layout < background_delta) { |
133 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", | 140 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", |
134 timing_.first_layout); | 141 timing_.first_layout); |
| 142 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); |
135 } else { | 143 } else { |
136 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", | 144 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", |
137 timing_.first_layout); | 145 timing_.first_layout); |
| 146 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); |
138 } | 147 } |
139 } | 148 } |
| 149 |
| 150 } |
| 151 |
| 152 void PageLoadTracker::RecordEvent(PageLoadEvent event) { |
| 153 UMA_HISTOGRAM_ENUMERATION( |
| 154 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); |
140 } | 155 } |
141 | 156 |
142 MetricsWebContentsObserver::MetricsWebContentsObserver( | 157 MetricsWebContentsObserver::MetricsWebContentsObserver( |
143 content::WebContents* web_contents) | 158 content::WebContents* web_contents) |
144 : content::WebContentsObserver(web_contents), in_foreground_(false) {} | 159 : content::WebContentsObserver(web_contents), in_foreground_(false) {} |
145 | 160 |
146 MetricsWebContentsObserver::~MetricsWebContentsObserver() {} | 161 MetricsWebContentsObserver::~MetricsWebContentsObserver() {} |
147 | 162 |
148 bool MetricsWebContentsObserver::OnMessageReceived( | 163 bool MetricsWebContentsObserver::OnMessageReceived( |
149 const IPC::Message& message, | 164 const IPC::Message& message, |
(...skipping 22 matching lines...) Expand all Loading... |
172 | 187 |
173 void MetricsWebContentsObserver::DidFinishNavigation( | 188 void MetricsWebContentsObserver::DidFinishNavigation( |
174 content::NavigationHandle* navigation_handle) { | 189 content::NavigationHandle* navigation_handle) { |
175 if (!navigation_handle->IsInMainFrame()) | 190 if (!navigation_handle->IsInMainFrame()) |
176 return; | 191 return; |
177 | 192 |
178 scoped_ptr<PageLoadTracker> finished_nav( | 193 scoped_ptr<PageLoadTracker> finished_nav( |
179 provisional_loads_.take_and_erase(navigation_handle)); | 194 provisional_loads_.take_and_erase(navigation_handle)); |
180 DCHECK(finished_nav); | 195 DCHECK(finished_nav); |
181 | 196 |
182 // TODO(csharrison) handle the two error cases: | 197 // Handle a pre-commit error here. Navigations that result in an error page |
183 // 1. Error pages that replace the previous page. | 198 // will be ignored. |
184 // 2. Error pages that leave the user on the previous page. | 199 if (!navigation_handle->HasCommitted()) { |
185 // For now these cases will be ignored. | 200 finished_nav->RecordEvent(PAGE_LOAD_FAILED_BEFORE_COMMIT); |
186 if (!navigation_handle->HasCommitted()) | 201 if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED) |
| 202 finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_COMMIT); |
187 return; | 203 return; |
| 204 } |
188 | 205 |
189 // Don't treat a same-page nav as a new page load. | 206 // Don't treat a same-page nav as a new page load. |
190 if (navigation_handle->IsSamePage()) | 207 if (navigation_handle->IsSamePage()) |
191 return; | 208 return; |
192 | 209 |
193 // Eagerly log the previous UMA even if we don't care about the current | 210 // Eagerly log the previous UMA even if we don't care about the current |
194 // navigation. | 211 // navigation. |
195 committed_load_.reset(); | 212 committed_load_.reset(); |
196 | 213 |
197 if (!IsRelevantNavigation(navigation_handle)) | 214 if (!IsRelevantNavigation(navigation_handle)) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 // sure here that we aren't logging UMA for internal pages. | 266 // sure here that we aren't logging UMA for internal pages. |
250 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | 267 const GURL& browser_url = web_contents()->GetLastCommittedURL(); |
251 return navigation_handle->IsInMainFrame() && | 268 return navigation_handle->IsInMainFrame() && |
252 !navigation_handle->IsSamePage() && | 269 !navigation_handle->IsSamePage() && |
253 !navigation_handle->IsErrorPage() && | 270 !navigation_handle->IsErrorPage() && |
254 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && | 271 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && |
255 browser_url.SchemeIsHTTPOrHTTPS(); | 272 browser_url.SchemeIsHTTPOrHTTPS(); |
256 } | 273 } |
257 | 274 |
258 } // namespace page_load_metrics | 275 } // namespace page_load_metrics |
OLD | NEW |