Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: chrome/browser/page_load_metrics/page_load_tracker.cc

Issue 2874663005: [Page Load Metrics] Add mojom file to page load metrics. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chrome/browser/page_load_metrics/page_load_tracker.h" 5 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 bool EventsInOrder(const base::Optional<base::TimeDelta>& first, 122 bool EventsInOrder(const base::Optional<base::TimeDelta>& first,
123 const base::Optional<base::TimeDelta>& second) { 123 const base::Optional<base::TimeDelta>& second) {
124 if (!second) { 124 if (!second) {
125 return true; 125 return true;
126 } 126 }
127 return first && first <= second; 127 return first && first <= second;
128 } 128 }
129 129
130 internal::PageLoadTimingStatus IsValidPageLoadTiming( 130 internal::PageLoadTimingStatus IsValidPageLoadTiming(
131 const PageLoadTiming& timing) { 131 const PageLoadTiming& timing) {
132 if (timing.IsEmpty()) 132 if (page_load_metrics::IsEmpty(timing))
133 return internal::INVALID_EMPTY_TIMING; 133 return internal::INVALID_EMPTY_TIMING;
134 134
135 // If we have a non-empty timing, it should always have a navigation start. 135 // If we have a non-empty timing, it should always have a navigation start.
136 if (timing.navigation_start.is_null()) { 136 if (timing.navigation_start.is_null()) {
137 LOG(ERROR) << "Received null navigation_start."; 137 LOG(ERROR) << "Received null navigation_start.";
138 return internal::INVALID_NULL_NAVIGATION_START; 138 return internal::INVALID_NULL_NAVIGATION_START;
139 } 139 }
140 140
141 // Verify proper ordering between the various timings. 141 // Verify proper ordering between the various timings.
142 142
143 if (!EventsInOrder(timing.response_start, timing.parse_timing.parse_start)) { 143 if (!EventsInOrder(timing.response_start, timing.parse_timing->parse_start)) {
144 // We sometimes get a zero response_start with a non-zero parse start. See 144 // We sometimes get a zero response_start with a non-zero parse start. See
145 // crbug.com/590212. 145 // crbug.com/590212.
146 LOG(ERROR) << "Invalid response_start " << timing.response_start 146 LOG(ERROR) << "Invalid response_start " << timing.response_start
147 << " for parse_start " << timing.parse_timing.parse_start; 147 << " for parse_start " << timing.parse_timing->parse_start;
148 // When browser-side navigation is enabled, we sometimes encounter this 148 // When browser-side navigation is enabled, we sometimes encounter this
149 // error case. For now, we disable reporting of this error, since most 149 // error case. For now, we disable reporting of this error, since most
150 // PageLoadMetricsObservers don't care about response_start and we want to 150 // PageLoadMetricsObservers don't care about response_start and we want to
151 // see how much closer fixing this error will get us to page load metrics 151 // see how much closer fixing this error will get us to page load metrics
152 // being consistent with and without browser side navigation enabled. See 152 // being consistent with and without browser side navigation enabled. See
153 // crbug.com/716587 for more details. 153 // crbug.com/716587 for more details.
154 // 154 //
155 // return internal::INVALID_ORDER_RESPONSE_START_PARSE_START; 155 // return internal::INVALID_ORDER_RESPONSE_START_PARSE_START;
156 } 156 }
157 157
158 if (!EventsInOrder(timing.parse_timing.parse_start, 158 if (!EventsInOrder(timing.parse_timing->parse_start,
159 timing.parse_timing.parse_stop)) { 159 timing.parse_timing->parse_stop)) {
160 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing.parse_start 160 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing->parse_start
161 << " for parse_stop " << timing.parse_timing.parse_stop; 161 << " for parse_stop " << timing.parse_timing->parse_stop;
162 return internal::INVALID_ORDER_PARSE_START_PARSE_STOP; 162 return internal::INVALID_ORDER_PARSE_START_PARSE_STOP;
163 } 163 }
164 164
165 if (timing.parse_timing.parse_stop) { 165 if (timing.parse_timing->parse_stop) {
166 const base::TimeDelta parse_duration = 166 const base::TimeDelta parse_duration =
167 timing.parse_timing.parse_stop.value() - 167 timing.parse_timing->parse_stop.value() -
168 timing.parse_timing.parse_start.value(); 168 timing.parse_timing->parse_start.value();
169 if (timing.parse_timing.parse_blocked_on_script_load_duration > 169 if (timing.parse_timing->parse_blocked_on_script_load_duration >
170 parse_duration) { 170 parse_duration) {
171 LOG(ERROR) << "Invalid parse_blocked_on_script_load_duration " 171 LOG(ERROR) << "Invalid parse_blocked_on_script_load_duration "
172 << timing.parse_timing.parse_blocked_on_script_load_duration 172 << timing.parse_timing->parse_blocked_on_script_load_duration
173 << " for parse duration " << parse_duration; 173 << " for parse duration " << parse_duration;
174 return internal::INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE; 174 return internal::INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE;
175 } 175 }
176 if (timing.parse_timing.parse_blocked_on_script_execution_duration > 176 if (timing.parse_timing->parse_blocked_on_script_execution_duration >
177 parse_duration) { 177 parse_duration) {
178 LOG(ERROR) 178 LOG(ERROR)
179 << "Invalid parse_blocked_on_script_execution_duration " 179 << "Invalid parse_blocked_on_script_execution_duration "
180 << timing.parse_timing.parse_blocked_on_script_execution_duration 180 << timing.parse_timing->parse_blocked_on_script_execution_duration
181 << " for parse duration " << parse_duration; 181 << " for parse duration " << parse_duration;
182 return internal::INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE; 182 return internal::INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE;
183 } 183 }
184 } 184 }
185 185
186 if (timing.parse_timing 186 if (timing.parse_timing
187 .parse_blocked_on_script_load_from_document_write_duration > 187 ->parse_blocked_on_script_load_from_document_write_duration >
188 timing.parse_timing.parse_blocked_on_script_load_duration) { 188 timing.parse_timing->parse_blocked_on_script_load_duration) {
189 LOG(ERROR) 189 LOG(ERROR)
190 << "Invalid parse_blocked_on_script_load_from_document_write_duration " 190 << "Invalid parse_blocked_on_script_load_from_document_write_duration "
191 << timing.parse_timing 191 << timing.parse_timing
192 .parse_blocked_on_script_load_from_document_write_duration 192 ->parse_blocked_on_script_load_from_document_write_duration
193 << " for parse_blocked_on_script_load_duration " 193 << " for parse_blocked_on_script_load_duration "
194 << timing.parse_timing.parse_blocked_on_script_load_duration; 194 << timing.parse_timing->parse_blocked_on_script_load_duration;
195 return internal::INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD; 195 return internal::INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD;
196 } 196 }
197 197
198 if (timing.parse_timing 198 if (timing.parse_timing
199 .parse_blocked_on_script_execution_from_document_write_duration > 199 ->parse_blocked_on_script_execution_from_document_write_duration >
200 timing.parse_timing.parse_blocked_on_script_execution_duration) { 200 timing.parse_timing->parse_blocked_on_script_execution_duration) {
201 LOG(ERROR) 201 LOG(ERROR)
202 << "Invalid " 202 << "Invalid "
203 "parse_blocked_on_script_execution_from_document_write_duration " 203 "parse_blocked_on_script_execution_from_document_write_duration "
204 << timing.parse_timing 204 << timing.parse_timing
205 .parse_blocked_on_script_execution_from_document_write_duration 205 ->parse_blocked_on_script_execution_from_document_write_duration
206 << " for parse_blocked_on_script_execution_duration " 206 << " for parse_blocked_on_script_execution_duration "
207 << timing.parse_timing.parse_blocked_on_script_execution_duration; 207 << timing.parse_timing->parse_blocked_on_script_execution_duration;
208 return internal::INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC; 208 return internal::INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC;
209 } 209 }
210 210
211 if (!EventsInOrder(timing.parse_timing.parse_stop, 211 if (!EventsInOrder(timing.parse_timing->parse_stop,
212 timing.document_timing.dom_content_loaded_event_start)) { 212 timing.document_timing->dom_content_loaded_event_start)) {
213 LOG(ERROR) << "Invalid parse_stop " << timing.parse_timing.parse_stop 213 LOG(ERROR) << "Invalid parse_stop " << timing.parse_timing->parse_stop
214 << " for dom_content_loaded_event_start " 214 << " for dom_content_loaded_event_start "
215 << timing.document_timing.dom_content_loaded_event_start; 215 << timing.document_timing->dom_content_loaded_event_start;
216 return internal::INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED; 216 return internal::INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED;
217 } 217 }
218 218
219 if (!EventsInOrder(timing.document_timing.dom_content_loaded_event_start, 219 if (!EventsInOrder(timing.document_timing->dom_content_loaded_event_start,
220 timing.document_timing.load_event_start)) { 220 timing.document_timing->load_event_start)) {
221 LOG(ERROR) << "Invalid dom_content_loaded_event_start " 221 LOG(ERROR) << "Invalid dom_content_loaded_event_start "
222 << timing.document_timing.dom_content_loaded_event_start 222 << timing.document_timing->dom_content_loaded_event_start
223 << " for load_event_start " 223 << " for load_event_start "
224 << timing.document_timing.load_event_start; 224 << timing.document_timing->load_event_start;
225 return internal::INVALID_ORDER_DOM_CONTENT_LOADED_LOAD; 225 return internal::INVALID_ORDER_DOM_CONTENT_LOADED_LOAD;
226 } 226 }
227 227
228 if (!EventsInOrder(timing.parse_timing.parse_start, 228 if (!EventsInOrder(timing.parse_timing->parse_start,
229 timing.document_timing.first_layout)) { 229 timing.document_timing->first_layout)) {
230 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing.parse_start 230 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing->parse_start
231 << " for first_layout " << timing.document_timing.first_layout; 231 << " for first_layout " << timing.document_timing->first_layout;
232 return internal::INVALID_ORDER_PARSE_START_FIRST_LAYOUT; 232 return internal::INVALID_ORDER_PARSE_START_FIRST_LAYOUT;
233 } 233 }
234 234
235 if (!EventsInOrder(timing.document_timing.first_layout, 235 if (!EventsInOrder(timing.document_timing->first_layout,
236 timing.paint_timing.first_paint)) { 236 timing.paint_timing->first_paint)) {
237 // This can happen when we process an XHTML document that doesn't contain 237 // This can happen when we process an XHTML document that doesn't contain
238 // well formed XML. See crbug.com/627607. 238 // well formed XML. See crbug.com/627607.
239 DLOG(ERROR) << "Invalid first_layout " 239 DLOG(ERROR) << "Invalid first_layout "
240 << timing.document_timing.first_layout << " for first_paint " 240 << timing.document_timing->first_layout << " for first_paint "
241 << timing.paint_timing.first_paint; 241 << timing.paint_timing->first_paint;
242 return internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT; 242 return internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT;
243 } 243 }
244 244
245 if (!EventsInOrder(timing.paint_timing.first_paint, 245 if (!EventsInOrder(timing.paint_timing->first_paint,
246 timing.paint_timing.first_text_paint)) { 246 timing.paint_timing->first_text_paint)) {
247 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 247 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
248 << " for first_text_paint " 248 << " for first_text_paint "
249 << timing.paint_timing.first_text_paint; 249 << timing.paint_timing->first_text_paint;
250 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT; 250 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT;
251 } 251 }
252 252
253 if (!EventsInOrder(timing.paint_timing.first_paint, 253 if (!EventsInOrder(timing.paint_timing->first_paint,
254 timing.paint_timing.first_image_paint)) { 254 timing.paint_timing->first_image_paint)) {
255 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 255 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
256 << " for first_image_paint " 256 << " for first_image_paint "
257 << timing.paint_timing.first_image_paint; 257 << timing.paint_timing->first_image_paint;
258 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT; 258 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT;
259 } 259 }
260 260
261 if (!EventsInOrder(timing.paint_timing.first_paint, 261 if (!EventsInOrder(timing.paint_timing->first_paint,
262 timing.paint_timing.first_contentful_paint)) { 262 timing.paint_timing->first_contentful_paint)) {
263 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 263 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
264 << " for first_contentful_paint " 264 << " for first_contentful_paint "
265 << timing.paint_timing.first_contentful_paint; 265 << timing.paint_timing->first_contentful_paint;
266 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT; 266 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT;
267 } 267 }
268 268
269 if (!EventsInOrder(timing.paint_timing.first_paint, 269 if (!EventsInOrder(timing.paint_timing->first_paint,
270 timing.paint_timing.first_meaningful_paint)) { 270 timing.paint_timing->first_meaningful_paint)) {
271 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 271 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
272 << " for first_meaningful_paint " 272 << " for first_meaningful_paint "
273 << timing.paint_timing.first_meaningful_paint; 273 << timing.paint_timing->first_meaningful_paint;
274 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT; 274 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT;
275 } 275 }
276 276
277 return internal::VALID; 277 return internal::VALID;
278 } 278 }
279 279
280 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) { 280 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) {
281 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground, 281 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground,
282 completed_after_background); 282 completed_after_background);
283 } 283 }
284 284
285 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, 285 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer,
286 const PageLoadTiming& last_timing, 286 const PageLoadTiming& last_timing,
287 const PageLoadTiming& new_timing, 287 const PageLoadTiming& new_timing,
288 const PageLoadMetadata& last_metadata, 288 const PageLoadMetadata& last_metadata,
289 const PageLoadExtraInfo& extra_info) { 289 const PageLoadExtraInfo& extra_info) {
290 if (extra_info.main_frame_metadata.behavior_flags != 290 if (extra_info.main_frame_metadata.behavior_flags !=
291 last_metadata.behavior_flags) 291 last_metadata.behavior_flags)
292 observer->OnLoadingBehaviorObserved(extra_info); 292 observer->OnLoadingBehaviorObserved(extra_info);
293 if (last_timing != new_timing) 293 if (!last_timing.Equals(new_timing))
294 observer->OnTimingUpdate(new_timing, extra_info); 294 observer->OnTimingUpdate(new_timing, extra_info);
295 if (new_timing.document_timing.dom_content_loaded_event_start && 295 if (new_timing.document_timing->dom_content_loaded_event_start &&
296 !last_timing.document_timing.dom_content_loaded_event_start) 296 !last_timing.document_timing->dom_content_loaded_event_start)
297 observer->OnDomContentLoadedEventStart(new_timing, extra_info); 297 observer->OnDomContentLoadedEventStart(new_timing, extra_info);
298 if (new_timing.document_timing.load_event_start && 298 if (new_timing.document_timing->load_event_start &&
299 !last_timing.document_timing.load_event_start) 299 !last_timing.document_timing->load_event_start)
300 observer->OnLoadEventStart(new_timing, extra_info); 300 observer->OnLoadEventStart(new_timing, extra_info);
301 if (new_timing.document_timing.first_layout && 301 if (new_timing.document_timing->first_layout &&
302 !last_timing.document_timing.first_layout) 302 !last_timing.document_timing->first_layout)
303 observer->OnFirstLayout(new_timing, extra_info); 303 observer->OnFirstLayout(new_timing, extra_info);
304 if (new_timing.paint_timing.first_paint && 304 if (new_timing.paint_timing->first_paint &&
305 !last_timing.paint_timing.first_paint) 305 !last_timing.paint_timing->first_paint)
306 observer->OnFirstPaint(new_timing, extra_info); 306 observer->OnFirstPaint(new_timing, extra_info);
307 if (new_timing.paint_timing.first_text_paint && 307 if (new_timing.paint_timing->first_text_paint &&
308 !last_timing.paint_timing.first_text_paint) 308 !last_timing.paint_timing->first_text_paint)
309 observer->OnFirstTextPaint(new_timing, extra_info); 309 observer->OnFirstTextPaint(new_timing, extra_info);
310 if (new_timing.paint_timing.first_image_paint && 310 if (new_timing.paint_timing->first_image_paint &&
311 !last_timing.paint_timing.first_image_paint) 311 !last_timing.paint_timing->first_image_paint)
312 observer->OnFirstImagePaint(new_timing, extra_info); 312 observer->OnFirstImagePaint(new_timing, extra_info);
313 if (new_timing.paint_timing.first_contentful_paint && 313 if (new_timing.paint_timing->first_contentful_paint &&
314 !last_timing.paint_timing.first_contentful_paint) 314 !last_timing.paint_timing->first_contentful_paint)
315 observer->OnFirstContentfulPaint(new_timing, extra_info); 315 observer->OnFirstContentfulPaint(new_timing, extra_info);
316 if (new_timing.paint_timing.first_meaningful_paint && 316 if (new_timing.paint_timing->first_meaningful_paint &&
317 !last_timing.paint_timing.first_meaningful_paint) 317 !last_timing.paint_timing->first_meaningful_paint)
318 observer->OnFirstMeaningfulPaint(new_timing, extra_info); 318 observer->OnFirstMeaningfulPaint(new_timing, extra_info);
319 if (new_timing.parse_timing.parse_start && 319 if (new_timing.parse_timing->parse_start &&
320 !last_timing.parse_timing.parse_start) 320 !last_timing.parse_timing->parse_start)
321 observer->OnParseStart(new_timing, extra_info); 321 observer->OnParseStart(new_timing, extra_info);
322 if (new_timing.parse_timing.parse_stop && 322 if (new_timing.parse_timing->parse_stop &&
323 !last_timing.parse_timing.parse_stop) 323 !last_timing.parse_timing->parse_stop)
324 observer->OnParseStop(new_timing, extra_info); 324 observer->OnParseStop(new_timing, extra_info);
325 } 325 }
326 326
327 } // namespace 327 } // namespace
328 328
329 PageLoadTracker::PageLoadTracker( 329 PageLoadTracker::PageLoadTracker(
330 bool in_foreground, 330 bool in_foreground,
331 PageLoadMetricsEmbedderInterface* embedder_interface, 331 PageLoadMetricsEmbedderInterface* embedder_interface,
332 const GURL& currently_committed_url, 332 const GURL& currently_committed_url,
333 content::NavigationHandle* navigation_handle, 333 content::NavigationHandle* navigation_handle,
334 UserInitiatedInfo user_initiated_info, 334 UserInitiatedInfo user_initiated_info,
335 int aborted_chain_size, 335 int aborted_chain_size,
336 int aborted_chain_size_same_url) 336 int aborted_chain_size_same_url)
337 : did_stop_tracking_(false), 337 : did_stop_tracking_(false),
338 app_entered_background_(false), 338 app_entered_background_(false),
339 navigation_start_(navigation_handle->NavigationStart()), 339 navigation_start_(navigation_handle->NavigationStart()),
340 url_(navigation_handle->GetURL()), 340 url_(navigation_handle->GetURL()),
341 start_url_(navigation_handle->GetURL()), 341 start_url_(navigation_handle->GetURL()),
342 did_commit_(false), 342 did_commit_(false),
343 page_end_reason_(END_NONE), 343 page_end_reason_(END_NONE),
344 page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()), 344 page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()),
345 started_in_foreground_(in_foreground), 345 started_in_foreground_(in_foreground),
346 timing_(CreatePageLoadTiming()),
346 page_transition_(navigation_handle->GetPageTransition()), 347 page_transition_(navigation_handle->GetPageTransition()),
347 user_initiated_info_(user_initiated_info), 348 user_initiated_info_(user_initiated_info),
348 aborted_chain_size_(aborted_chain_size), 349 aborted_chain_size_(aborted_chain_size),
349 aborted_chain_size_same_url_(aborted_chain_size_same_url), 350 aborted_chain_size_same_url_(aborted_chain_size_same_url),
350 embedder_interface_(embedder_interface) { 351 embedder_interface_(embedder_interface) {
351 DCHECK(!navigation_handle->HasCommitted()); 352 DCHECK(!navigation_handle->HasCommitted());
352 embedder_interface_->RegisterObservers(this); 353 embedder_interface_->RegisterObservers(this);
353 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnStart, navigation_handle, 354 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnStart, navigation_handle,
354 currently_committed_url, started_in_foreground_); 355 currently_committed_url, started_in_foreground_);
355 356
(...skipping 27 matching lines...) Expand all
383 if (!failed_provisional_load_info_) 384 if (!failed_provisional_load_info_)
384 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD); 385 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD);
385 386
386 // Don't include any aborts that resulted in a new navigation, as the chain 387 // Don't include any aborts that resulted in a new navigation, as the chain
387 // length will be included in the aborter PageLoadTracker. 388 // length will be included in the aborter PageLoadTracker.
388 if (page_end_reason_ != END_RELOAD && 389 if (page_end_reason_ != END_RELOAD &&
389 page_end_reason_ != END_FORWARD_BACK && 390 page_end_reason_ != END_FORWARD_BACK &&
390 page_end_reason_ != END_NEW_NAVIGATION) { 391 page_end_reason_ != END_NEW_NAVIGATION) {
391 LogAbortChainHistograms(nullptr); 392 LogAbortChainHistograms(nullptr);
392 } 393 }
393 } else if (timing_.IsEmpty()) { 394 } else if (page_load_metrics::IsEmpty(*timing_)) {
394 RecordInternalError(ERR_NO_IPCS_RECEIVED); 395 RecordInternalError(ERR_NO_IPCS_RECEIVED);
395 } 396 }
396 397
397 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 398 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
398 for (const auto& observer : observers_) { 399 for (const auto& observer : observers_) {
399 if (failed_provisional_load_info_) { 400 if (failed_provisional_load_info_) {
400 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info); 401 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info);
401 } else if (did_commit_) { 402 } else if (did_commit_) {
402 observer->OnComplete(timing_, info); 403 observer->OnComplete(*timing_, info);
403 } 404 }
404 } 405 }
405 } 406 }
406 407
407 void PageLoadTracker::LogAbortChainHistograms( 408 void PageLoadTracker::LogAbortChainHistograms(
408 content::NavigationHandle* final_navigation) { 409 content::NavigationHandle* final_navigation) {
409 if (aborted_chain_size_ == 0) 410 if (aborted_chain_size_ == 0)
410 return; 411 return;
411 // Note that this could be broken out by this navigation's abort type, if more 412 // Note that this could be broken out by this navigation's abort type, if more
412 // granularity is needed. Add one to the chain size to count the current 413 // granularity is needed. Add one to the chain size to count the current
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 // Only log the first time we background in a given page load. 460 // Only log the first time we background in a given page load.
460 if (background_time_.is_null()) { 461 if (background_time_.is_null()) {
461 // Make sure we either started in the foreground and haven't been 462 // Make sure we either started in the foreground and haven't been
462 // foregrounded yet, or started in the background and have already been 463 // foregrounded yet, or started in the background and have already been
463 // foregrounded. 464 // foregrounded.
464 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null()); 465 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
465 background_time_ = base::TimeTicks::Now(); 466 background_time_ = base::TimeTicks::Now();
466 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_); 467 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
467 } 468 }
468 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 469 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
469 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnHidden, timing_, info); 470 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnHidden, *timing_, info);
470 } 471 }
471 472
472 void PageLoadTracker::WebContentsShown() { 473 void PageLoadTracker::WebContentsShown() {
473 // Only log the first time we foreground in a given page load. 474 // Only log the first time we foreground in a given page load.
474 if (foreground_time_.is_null()) { 475 if (foreground_time_.is_null()) {
475 // Make sure we either started in the background and haven't been 476 // Make sure we either started in the background and haven't been
476 // backgrounded yet, or started in the foreground and have already been 477 // backgrounded yet, or started in the foreground and have already been
477 // backgrounded. 478 // backgrounded.
478 DCHECK_NE(started_in_foreground_, background_time_.is_null()); 479 DCHECK_NE(started_in_foreground_, background_time_.is_null());
479 foreground_time_ = base::TimeTicks::Now(); 480 foreground_time_ = base::TimeTicks::Now();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 543 }
543 544
544 void PageLoadTracker::FlushMetricsOnAppEnterBackground() { 545 void PageLoadTracker::FlushMetricsOnAppEnterBackground() {
545 if (!app_entered_background_) { 546 if (!app_entered_background_) {
546 RecordAppBackgroundPageLoadCompleted(false); 547 RecordAppBackgroundPageLoadCompleted(false);
547 app_entered_background_ = true; 548 app_entered_background_ = true;
548 } 549 }
549 550
550 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 551 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
551 INVOKE_AND_PRUNE_OBSERVERS(observers_, FlushMetricsOnAppEnterBackground, 552 INVOKE_AND_PRUNE_OBSERVERS(observers_, FlushMetricsOnAppEnterBackground,
552 timing_, info); 553 *timing_, info);
553 } 554 }
554 555
555 void PageLoadTracker::NotifyClientRedirectTo( 556 void PageLoadTracker::NotifyClientRedirectTo(
556 const PageLoadTracker& destination) { 557 const PageLoadTracker& destination) {
557 if (timing_.paint_timing.first_paint) { 558 if (timing_->paint_timing->first_paint) {
558 base::TimeTicks first_paint_time = 559 base::TimeTicks first_paint_time =
559 navigation_start() + timing_.paint_timing.first_paint.value(); 560 navigation_start() + timing_->paint_timing->first_paint.value();
560 base::TimeDelta first_paint_to_navigation; 561 base::TimeDelta first_paint_to_navigation;
561 if (destination.navigation_start() > first_paint_time) 562 if (destination.navigation_start() > first_paint_time)
562 first_paint_to_navigation = 563 first_paint_to_navigation =
563 destination.navigation_start() - first_paint_time; 564 destination.navigation_start() - first_paint_time;
564 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, 565 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation,
565 first_paint_to_navigation); 566 first_paint_to_navigation);
566 } else { 567 } else {
567 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); 568 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true);
568 } 569 }
569 } 570 }
(...skipping 14 matching lines...) Expand all
584 } 585 }
585 } 586 }
586 587
587 void PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, 588 void PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing,
588 const PageLoadMetadata& new_metadata) { 589 const PageLoadMetadata& new_metadata) {
589 // Throw away IPCs that are not relevant to the current navigation. 590 // Throw away IPCs that are not relevant to the current navigation.
590 // Two timing structures cannot refer to the same navigation if they indicate 591 // Two timing structures cannot refer to the same navigation if they indicate
591 // that a navigation started at different times, so a new timing struct with a 592 // that a navigation started at different times, so a new timing struct with a
592 // different start time from an earlier struct is considered invalid. 593 // different start time from an earlier struct is considered invalid.
593 const bool valid_timing_descendent = 594 const bool valid_timing_descendent =
594 timing_.navigation_start.is_null() || 595 timing_->navigation_start.is_null() ||
595 timing_.navigation_start == new_timing.navigation_start; 596 timing_->navigation_start == new_timing.navigation_start;
596 if (!valid_timing_descendent) { 597 if (!valid_timing_descendent) {
597 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT); 598 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT);
598 return; 599 return;
599 } 600 }
600 601
601 // Ensure flags sent previously are still present in the new metadata fields. 602 // Ensure flags sent previously are still present in the new metadata fields.
602 const bool valid_behavior_descendent = 603 const bool valid_behavior_descendent =
603 (main_frame_metadata_.behavior_flags & new_metadata.behavior_flags) == 604 (main_frame_metadata_.behavior_flags & new_metadata.behavior_flags) ==
604 main_frame_metadata_.behavior_flags; 605 main_frame_metadata_.behavior_flags;
605 if (!valid_behavior_descendent) { 606 if (!valid_behavior_descendent) {
606 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT); 607 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT);
607 return; 608 return;
608 } 609 }
609 internal::PageLoadTimingStatus status = IsValidPageLoadTiming(new_timing); 610 internal::PageLoadTimingStatus status = IsValidPageLoadTiming(new_timing);
610 UMA_HISTOGRAM_ENUMERATION(internal::kPageLoadTimingStatus, status, 611 UMA_HISTOGRAM_ENUMERATION(internal::kPageLoadTimingStatus, status,
611 internal::LAST_PAGE_LOAD_TIMING_STATUS); 612 internal::LAST_PAGE_LOAD_TIMING_STATUS);
612 if (status != internal::VALID) { 613 if (status != internal::VALID) {
613 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING); 614 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING);
614 return; 615 return;
615 } 616 }
616 617
617 DCHECK(did_commit_); // OnCommit() must be called first. 618 DCHECK(did_commit_); // OnCommit() must be called first.
618 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() 619 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo()
619 // must be called before DispatchObserverTimingCallbacks, but its 620 // must be called before DispatchObserverTimingCallbacks, but its
620 // implementation depends on the state of main_frame_metadata_, so we need 621 // implementation depends on the state of main_frame_metadata_, so we need
621 // to update main_frame_metadata_ before calling GetPageLoadMetricsInfo. 622 // to update main_frame_metadata_ before calling GetPageLoadMetricsInfo.
622 // Thus, we make a copy of timing here, update timing_ and 623 // Thus, we make a copy of timing here, update timing_ and
623 // main_frame_metadata_, and then proceed to dispatch the observer timing 624 // main_frame_metadata_, and then proceed to dispatch the observer timing
624 // callbacks. 625 // callbacks.
625 const PageLoadTiming last_timing = timing_; 626 mojo::StructPtr<PageLoadTiming> last_timing = std::move(timing_);
626 timing_ = new_timing; 627 timing_ = new_timing.Clone();
627 628
628 const PageLoadMetadata last_metadata = main_frame_metadata_; 629 const PageLoadMetadata last_metadata = main_frame_metadata_;
629 main_frame_metadata_ = new_metadata; 630 main_frame_metadata_ = new_metadata;
630 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 631 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
631 for (const auto& observer : observers_) { 632 for (const auto& observer : observers_) {
632 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, 633 DispatchObserverTimingCallbacks(observer.get(), *last_timing, new_timing,
633 last_metadata, info); 634 last_metadata, info);
634 } 635 }
635 } 636 }
636 637
637 void PageLoadTracker::OnStartedResource( 638 void PageLoadTracker::OnStartedResource(
638 const ExtraRequestStartInfo& extra_request_start_info) { 639 const ExtraRequestStartInfo& extra_request_start_info) {
639 for (const auto& observer : observers_) { 640 for (const auto& observer : observers_) {
640 observer->OnStartedResource(extra_request_start_info); 641 observer->OnStartedResource(extra_request_start_info);
641 } 642 }
642 } 643 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 observer->MediaStartedPlaying(video_type, is_in_main_frame); 820 observer->MediaStartedPlaying(video_type, is_in_main_frame);
820 } 821 }
821 822
822 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay, 823 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay,
823 base::TimeDelta actual_delay) { 824 base::TimeDelta actual_delay) {
824 for (const auto& observer : observers_) 825 for (const auto& observer : observers_)
825 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay); 826 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay);
826 } 827 }
827 828
828 } // namespace page_load_metrics 829 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698