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/location.h" | 7 #include "base/location.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "components/page_load_metrics/browser/page_load_metrics_macros.h" | 10 #include "components/page_load_metrics/browser/page_load_metrics_macros.h" |
11 #include "components/page_load_metrics/common/page_load_metrics_messages.h" | 11 #include "components/page_load_metrics/common/page_load_metrics_messages.h" |
12 #include "components/page_load_metrics/common/page_load_timing.h" | 12 #include "components/page_load_metrics/common/page_load_timing.h" |
13 #include "components/rappor/rappor_service.h" | 13 #include "components/rappor/rappor_service.h" |
14 #include "components/rappor/rappor_utils.h" | 14 #include "components/rappor/rappor_utils.h" |
15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
16 #include "content/public/browser/navigation_details.h" | 16 #include "content/public/browser/navigation_details.h" |
17 #include "content/public/browser/navigation_handle.h" | 17 #include "content/public/browser/navigation_handle.h" |
18 #include "content/public/browser/render_frame_host.h" | 18 #include "content/public/browser/render_frame_host.h" |
19 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
20 #include "content/public/browser/web_contents_observer.h" | 20 #include "content/public/browser/web_contents_observer.h" |
21 #include "content/public/browser/web_contents_user_data.h" | 21 #include "content/public/browser/web_contents_user_data.h" |
22 #include "ipc/ipc_message.h" | 22 #include "ipc/ipc_message.h" |
23 #include "ipc/ipc_message_macros.h" | 23 #include "ipc/ipc_message_macros.h" |
24 #include "ui/base/page_transition_types.h" | |
24 | 25 |
25 DEFINE_WEB_CONTENTS_USER_DATA_KEY( | 26 DEFINE_WEB_CONTENTS_USER_DATA_KEY( |
26 page_load_metrics::MetricsWebContentsObserver); | 27 page_load_metrics::MetricsWebContentsObserver); |
27 | 28 |
28 namespace page_load_metrics { | 29 namespace page_load_metrics { |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
32 // The url we see from the renderer side is not always the same as what | 33 // The url we see from the renderer side is not always the same as what |
33 // we see from the browser side (e.g. chrome://newtab). We want to be | 34 // we see from the browser side (e.g. chrome://newtab). We want to be |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 return false; | 74 return false; |
74 } | 75 } |
75 | 76 |
76 return true; | 77 return true; |
77 } | 78 } |
78 | 79 |
79 void RecordInternalError(InternalErrorLoadEvent event) { | 80 void RecordInternalError(InternalErrorLoadEvent event) { |
80 UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY); | 81 UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY); |
81 } | 82 } |
82 | 83 |
84 UserAbortType AbortTypeForPageTransition(ui::PageTransition transition) { | |
85 if (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD)) | |
86 return ABORT_RELOAD; | |
87 else if (transition & ui::PAGE_TRANSITION_FORWARD_BACK) | |
88 return ABORT_FORWARD_BACK; | |
89 else | |
90 return ABORT_NEW_NAVIGATION; | |
91 } | |
92 | |
83 base::TimeDelta GetFirstContentfulPaint(const PageLoadTiming& timing) { | 93 base::TimeDelta GetFirstContentfulPaint(const PageLoadTiming& timing) { |
84 if (timing.first_text_paint.is_zero()) | 94 if (timing.first_text_paint.is_zero()) |
85 return timing.first_image_paint; | 95 return timing.first_image_paint; |
86 if (timing.first_image_paint.is_zero()) | 96 if (timing.first_image_paint.is_zero()) |
87 return timing.first_text_paint; | 97 return timing.first_text_paint; |
88 return std::min(timing.first_text_paint, timing.first_image_paint); | 98 return std::min(timing.first_text_paint, timing.first_image_paint); |
89 } | 99 } |
90 | 100 |
91 // The number of buckets in the bitfield histogram. These buckets are described | 101 // The number of buckets in the bitfield histogram. These buckets are described |
92 // in rappor.xml in PageLoad.CoarseTiming.NavigationToFirstContentfulPaint. | 102 // in rappor.xml in PageLoad.CoarseTiming.NavigationToFirstContentfulPaint. |
(...skipping 20 matching lines...) Expand all Loading... | |
113 | 123 |
114 } // namespace | 124 } // namespace |
115 | 125 |
116 PageLoadTracker::PageLoadTracker( | 126 PageLoadTracker::PageLoadTracker( |
117 bool in_foreground, | 127 bool in_foreground, |
118 PageLoadMetricsEmbedderInterface* embedder_interface, | 128 PageLoadMetricsEmbedderInterface* embedder_interface, |
119 content::NavigationHandle* navigation_handle, | 129 content::NavigationHandle* navigation_handle, |
120 base::ObserverList<PageLoadMetricsObserver, true>* observers) | 130 base::ObserverList<PageLoadMetricsObserver, true>* observers) |
121 : has_commit_(false), | 131 : has_commit_(false), |
122 navigation_start_(navigation_handle->navigation_start()), | 132 navigation_start_(navigation_handle->navigation_start()), |
133 abort_type_(ABORT_NULL), | |
123 started_in_foreground_(in_foreground), | 134 started_in_foreground_(in_foreground), |
124 embedder_interface_(embedder_interface), | 135 embedder_interface_(embedder_interface), |
125 observers_(observers) {} | 136 observers_(observers) {} |
126 | 137 |
127 PageLoadTracker::~PageLoadTracker() { | 138 PageLoadTracker::~PageLoadTracker() { |
128 if (has_commit_) { | 139 if (has_commit_) { |
129 RecordTimingHistograms(); | 140 RecordTimingHistograms(); |
130 RecordRappor(); | 141 RecordRappor(); |
131 } | 142 } |
143 RecordAbortTimingHistograms(); | |
132 } | 144 } |
133 | 145 |
134 void PageLoadTracker::WebContentsHidden() { | 146 void PageLoadTracker::WebContentsHidden() { |
135 // Only log the first time we background in a given page load. | 147 // Only log the first time we background in a given page load. |
136 if (started_in_foreground_ && background_time_.is_null()) | 148 if (started_in_foreground_ && background_time_.is_null()) |
137 background_time_ = base::TimeTicks::Now(); | 149 background_time_ = base::TimeTicks::Now(); |
138 } | 150 } |
139 | 151 |
140 void PageLoadTracker::WebContentsShown() { | 152 void PageLoadTracker::WebContentsShown() { |
141 // Only log the first time we foreground in a given page load. | 153 // Only log the first time we foreground in a given page load. |
(...skipping 29 matching lines...) Expand all Loading... | |
171 return false; | 183 return false; |
172 } | 184 } |
173 | 185 |
174 bool PageLoadTracker::HasBackgrounded() { | 186 bool PageLoadTracker::HasBackgrounded() { |
175 return !started_in_foreground_ || !background_time_.is_null(); | 187 return !started_in_foreground_ || !background_time_.is_null(); |
176 } | 188 } |
177 | 189 |
178 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { | 190 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { |
179 base::TimeDelta first_background_time; | 191 base::TimeDelta first_background_time; |
180 base::TimeDelta first_foreground_time; | 192 base::TimeDelta first_foreground_time; |
181 if (!background_time_.is_null() && started_in_foreground_) | 193 if (!background_time_.is_null()) |
182 first_background_time = background_time_ - navigation_start_; | 194 first_background_time = background_time_ - navigation_start_; |
183 if (!foreground_time_.is_null() && !started_in_foreground_) | 195 if (!foreground_time_.is_null()) |
184 first_foreground_time = foreground_time_ - navigation_start_; | 196 first_foreground_time = foreground_time_ - navigation_start_; |
185 return PageLoadExtraInfo(first_background_time, first_foreground_time, | 197 return PageLoadExtraInfo(first_background_time, first_foreground_time, |
186 started_in_foreground_); | 198 started_in_foreground_); |
187 } | 199 } |
188 | 200 |
201 // We consider the first abort passed here as the true abort, unless it is | |
202 // ABORT_OTHER, so call this with decreasing specificity. | |
203 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, | |
204 const base::TimeTicks& timestamp) { | |
205 DCHECK(abort_type != ABORT_NULL); | |
206 if (abort_type_ == ABORT_NULL) { | |
207 abort_type_ = abort_type; | |
208 abort_time_ = timestamp; | |
209 } | |
210 | |
211 // If we got a better signal than ABORT_OTHER since the last navigation, treat | |
212 // it as the cause of the abort (Some ABORT_OTHER signals occur before the | |
213 // true signal). Note that this only occurs for provisional loads. While this | |
214 // heuristic is coarse, it works better and is simpler than other feasible | |
215 // methods. | |
216 if (abort_type_ == ABORT_OTHER && abort_type != ABORT_OTHER) { | |
217 abort_type_ = abort_type; | |
218 abort_time_ = std::min(abort_time_, timestamp); | |
219 } | |
220 } | |
221 | |
222 void PageLoadTracker::RecordAbortTimingHistograms() { | |
223 // Log the background "abort" if we backgrounded a foregrounded page before | |
224 // its first paint. This is a slightly different notion of abort (we can still | |
225 // get to the first paint later), but it is still worthwhile measure. | |
226 if (!background_time_.is_null() && | |
227 (timing_.first_paint.is_zero() || | |
228 GetBackgroundDelta() < timing_.first_paint)) { | |
229 if (has_commit_) { | |
230 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortBackground, | |
Bryan McQuade
2015/11/17 13:33:08
this does feel like a user-initiated abort, but i
Charlie Harrison
2015/11/17 16:11:54
I could go either way. I only put it here because
| |
231 background_time_ - navigation_start_); | |
232 } else { | |
233 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortBackground, | |
234 background_time_ - navigation_start_); | |
235 } | |
236 } | |
237 if (abort_type_ == ABORT_NULL) | |
238 return; | |
239 DCHECK(!abort_time_.is_null()); | |
240 | |
241 // Loads are not considered aborts if they painted before the abort event. | |
Bryan McQuade
2015/11/17 13:33:08
i'm inclined to either ignore aborts when a tab is
Charlie Harrison
2015/11/17 16:11:54
I'm inclined to ignore them for now and add later
| |
242 base::TimeDelta time_to_abort = abort_time_ - navigation_start_; | |
243 if (!timing_.first_paint.is_zero() && timing_.first_paint < time_to_abort) | |
244 return; | |
245 if (has_commit_) { | |
246 if (abort_type_ == ABORT_RELOAD) { | |
247 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortReload, time_to_abort); | |
248 } else if (abort_type_ == ABORT_FORWARD_BACK) { | |
249 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortForwardBack, time_to_abort); | |
250 } else if (abort_type_ == ABORT_NEW_NAVIGATION) { | |
251 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortNewNavigation, time_to_abort); | |
252 } else if (abort_type_ == ABORT_STOP) { | |
253 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortStop, time_to_abort); | |
254 } else if (abort_type_ == ABORT_CLOSE) { | |
255 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortClose, time_to_abort); | |
256 } else if (abort_type_ == ABORT_OTHER) { | |
257 PAGE_LOAD_HISTOGRAM(kHistogramCommittedAbortOther, time_to_abort); | |
258 } | |
259 } else { | |
260 if (abort_type_ == ABORT_RELOAD) { | |
261 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortReload, time_to_abort); | |
262 } else if (abort_type_ == ABORT_FORWARD_BACK) { | |
263 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortForwardBack, time_to_abort); | |
264 } else if (abort_type_ == ABORT_NEW_NAVIGATION) { | |
265 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortNewNavigation, | |
266 time_to_abort); | |
267 } else if (abort_type_ == ABORT_STOP) { | |
268 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortStop, time_to_abort); | |
269 } else if (abort_type_ == ABORT_CLOSE) { | |
270 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortClose, time_to_abort); | |
271 } else if (abort_type_ == ABORT_OTHER) { | |
272 PAGE_LOAD_HISTOGRAM(kHistogramProvisionalAbortOther, time_to_abort); | |
273 } | |
274 } | |
275 } | |
276 | |
189 const GURL& PageLoadTracker::GetCommittedURL() { | 277 const GURL& PageLoadTracker::GetCommittedURL() { |
190 DCHECK(has_commit_); | 278 DCHECK(has_commit_); |
191 return url_; | 279 return url_; |
192 } | 280 } |
193 | 281 |
194 // Blink calculates navigation start using TimeTicks, but converts to epoch time | 282 // Blink calculates navigation start using TimeTicks, but converts to epoch time |
195 // in its public API. Thus, to compare time values to navigation start, we | 283 // in its public API. Thus, to compare time values to navigation start, we |
196 // calculate the current time since the epoch using TimeTicks, and convert to | 284 // calculate the current time since the epoch using TimeTicks, and convert to |
197 // Time. This method is similar to how blink converts TimeTicks to epoch time. | 285 // Time. This method is similar to how blink converts TimeTicks to epoch time. |
198 // There may be slight inaccuracies due to inter-process timestamps, but | 286 // There may be slight inaccuracies due to inter-process timestamps, but |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 if (!metrics) { | 451 if (!metrics) { |
364 metrics = | 452 metrics = |
365 new MetricsWebContentsObserver(web_contents, embedder_interface.Pass()); | 453 new MetricsWebContentsObserver(web_contents, embedder_interface.Pass()); |
366 web_contents->SetUserData(UserDataKey(), metrics); | 454 web_contents->SetUserData(UserDataKey(), metrics); |
367 } | 455 } |
368 return metrics; | 456 return metrics; |
369 } | 457 } |
370 | 458 |
371 MetricsWebContentsObserver::~MetricsWebContentsObserver() { | 459 MetricsWebContentsObserver::~MetricsWebContentsObserver() { |
372 // Reset PageLoadTrackers so observers get final notifications. | 460 // Reset PageLoadTrackers so observers get final notifications. |
461 NotifyAbortAllLoads(ABORT_CLOSE); | |
373 committed_load_.reset(); | 462 committed_load_.reset(); |
374 provisional_loads_.clear(); | 463 provisional_loads_.clear(); |
464 aborted_provisional_loads_.clear(); | |
375 FOR_EACH_OBSERVER(PageLoadMetricsObserver, observers_, | 465 FOR_EACH_OBSERVER(PageLoadMetricsObserver, observers_, |
376 OnPageLoadMetricsGoingAway()); | 466 OnPageLoadMetricsGoingAway()); |
377 } | 467 } |
378 | 468 |
379 void MetricsWebContentsObserver::AddObserver( | 469 void MetricsWebContentsObserver::AddObserver( |
380 PageLoadMetricsObserver* observer) { | 470 PageLoadMetricsObserver* observer) { |
381 observers_.AddObserver(observer); | 471 observers_.AddObserver(observer); |
382 } | 472 } |
383 | 473 |
384 void MetricsWebContentsObserver::RemoveObserver( | 474 void MetricsWebContentsObserver::RemoveObserver( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 scoped_ptr<PageLoadTracker> finished_nav( | 516 scoped_ptr<PageLoadTracker> finished_nav( |
427 provisional_loads_.take_and_erase(navigation_handle)); | 517 provisional_loads_.take_and_erase(navigation_handle)); |
428 // There's a chance a navigation could have started before we were added to a | 518 // There's a chance a navigation could have started before we were added to a |
429 // tab. Bail out early if this is the case. | 519 // tab. Bail out early if this is the case. |
430 if (!finished_nav) | 520 if (!finished_nav) |
431 return; | 521 return; |
432 | 522 |
433 // Handle a pre-commit error here. Navigations that result in an error page | 523 // Handle a pre-commit error here. Navigations that result in an error page |
434 // will be ignored. Note that downloads/204s will result in HasCommitted() | 524 // will be ignored. Note that downloads/204s will result in HasCommitted() |
435 // returning false. | 525 // returning false. |
526 // TODO(csharrison): Track changes to NavigationHandle for signals when this | |
527 // is the case (HTTP response headers). | |
436 if (!navigation_handle->HasCommitted()) { | 528 if (!navigation_handle->HasCommitted()) { |
437 net::Error error = navigation_handle->GetNetErrorCode(); | 529 net::Error error = navigation_handle->GetNetErrorCode(); |
438 finished_nav->RecordProvisionalEvent( | 530 ProvisionalLoadEvent event = error == net::OK ? PROVISIONAL_LOAD_STOPPED |
439 error == net::OK ? PROVISIONAL_LOAD_STOPPED | |
440 : error == net::ERR_ABORTED ? PROVISIONAL_LOAD_ERR_ABORTED | 531 : error == net::ERR_ABORTED ? PROVISIONAL_LOAD_ERR_ABORTED |
Bryan McQuade
2015/11/17 13:33:08
IIRC downloads/204s report ERR_ABORTED, so we'll e
Charlie Harrison
2015/11/17 16:11:54
Let's see. It's possible clamy@ will land her chan
| |
441 : PROVISIONAL_LOAD_ERR_FAILED_NON_ABORT); | 532 : PROVISIONAL_LOAD_ERR_FAILED_NON_ABORT; |
533 finished_nav->RecordProvisionalEvent(event); | |
534 if (event != PROVISIONAL_LOAD_ERR_FAILED_NON_ABORT) { | |
535 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now()); | |
536 aborted_provisional_loads_.push_back(finished_nav.Pass()); | |
Bryan McQuade
2015/11/17 13:33:08
the aborted_provisional_loads_ member makes me a b
| |
537 } | |
442 return; | 538 return; |
443 } | 539 } |
444 finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_COMMITTED); | 540 finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_COMMITTED); |
Bryan McQuade
2015/11/17 13:33:08
just noticing now - unrelated to this change - sho
Charlie Harrison
2015/11/17 16:11:54
This was intentional. If we want we can break up t
| |
445 | 541 |
446 // Don't treat a same-page nav as a new page load. | 542 // Don't treat a same-page nav as a new page load. |
447 if (navigation_handle->IsSamePage()) | 543 if (navigation_handle->IsSamePage()) |
448 return; | 544 return; |
449 | 545 |
546 // Notify other loads that they may have been aborted by this committed load | |
547 NotifyAbortAllLoadsWithTimestamp( | |
548 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), | |
549 navigation_handle->navigation_start()); | |
550 | |
450 // Eagerly log the previous UMA even if we don't care about the current | 551 // Eagerly log the previous UMA even if we don't care about the current |
451 // navigation. | 552 // navigation. |
452 committed_load_.reset(); | 553 committed_load_.reset(); |
453 | 554 |
454 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | 555 const GURL& browser_url = web_contents()->GetLastCommittedURL(); |
455 const std::string& mime_type = web_contents()->GetContentsMimeType(); | 556 const std::string& mime_type = web_contents()->GetContentsMimeType(); |
456 DCHECK(!browser_url.is_empty()); | 557 DCHECK(!browser_url.is_empty()); |
457 DCHECK(!mime_type.empty()); | 558 DCHECK(!mime_type.empty()); |
458 if (!IsRelevantNavigation(navigation_handle, browser_url, mime_type)) | 559 if (!IsRelevantNavigation(navigation_handle, browser_url, mime_type)) |
459 return; | 560 return; |
460 | 561 |
461 committed_load_ = finished_nav.Pass(); | 562 committed_load_ = finished_nav.Pass(); |
462 committed_load_->Commit(navigation_handle); | 563 committed_load_->Commit(navigation_handle); |
564 aborted_provisional_loads_.clear(); | |
Bryan McQuade
2015/11/17 13:33:08
should we clear aborted_provisional_loads_ even if
Charlie Harrison
2015/11/17 16:11:54
Yupp good idea. Done.
| |
565 } | |
566 | |
567 void MetricsWebContentsObserver::NavigationStopped() { | |
568 NotifyAbortAllLoads(ABORT_STOP); | |
463 } | 569 } |
464 | 570 |
465 void MetricsWebContentsObserver::WasShown() { | 571 void MetricsWebContentsObserver::WasShown() { |
466 in_foreground_ = true; | 572 in_foreground_ = true; |
467 if (committed_load_) | 573 if (committed_load_) |
468 committed_load_->WebContentsShown(); | 574 committed_load_->WebContentsShown(); |
469 for (const auto& kv : provisional_loads_) { | 575 for (const auto& kv : provisional_loads_) { |
470 kv.second->WebContentsShown(); | 576 kv.second->WebContentsShown(); |
471 } | 577 } |
472 } | 578 } |
473 | 579 |
474 void MetricsWebContentsObserver::WasHidden() { | 580 void MetricsWebContentsObserver::WasHidden() { |
475 in_foreground_ = false; | 581 in_foreground_ = false; |
476 if (committed_load_) | 582 if (committed_load_) |
477 committed_load_->WebContentsHidden(); | 583 committed_load_->WebContentsHidden(); |
478 for (const auto& kv : provisional_loads_) { | 584 for (const auto& kv : provisional_loads_) { |
479 kv.second->WebContentsHidden(); | 585 kv.second->WebContentsHidden(); |
480 } | 586 } |
481 } | 587 } |
482 | 588 |
483 // This will occur when the process for the main RenderFrameHost exits, either | 589 // This will occur when the process for the main RenderFrameHost exits, either |
484 // normally or from a crash. We eagerly log data from the last committed load if | 590 // normally or from a crash. We eagerly log data from the last committed load if |
485 // we have one. | 591 // we have one. |
486 void MetricsWebContentsObserver::RenderProcessGone( | 592 void MetricsWebContentsObserver::RenderProcessGone( |
487 base::TerminationStatus status) { | 593 base::TerminationStatus status) { |
594 NotifyAbortAllLoads(ABORT_CLOSE); | |
488 committed_load_.reset(); | 595 committed_load_.reset(); |
596 provisional_loads_.clear(); | |
597 aborted_provisional_loads_.clear(); | |
598 } | |
599 | |
600 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { | |
601 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now()); | |
602 } | |
603 | |
604 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( | |
605 UserAbortType abort_type, const base::TimeTicks& timestamp) { | |
606 if (committed_load_) | |
607 committed_load_->NotifyAbort(abort_type, timestamp); | |
608 for (const auto& kv : provisional_loads_) { | |
609 kv.second->NotifyAbort(abort_type, timestamp); | |
610 } | |
611 for (const auto& plt : aborted_provisional_loads_) { | |
612 plt->NotifyAbort(abort_type, timestamp); | |
613 } | |
489 } | 614 } |
490 | 615 |
491 void MetricsWebContentsObserver::OnTimingUpdated( | 616 void MetricsWebContentsObserver::OnTimingUpdated( |
492 content::RenderFrameHost* render_frame_host, | 617 content::RenderFrameHost* render_frame_host, |
493 const PageLoadTiming& timing) { | 618 const PageLoadTiming& timing) { |
494 bool error = false; | 619 bool error = false; |
495 if (!committed_load_) { | 620 if (!committed_load_) { |
496 RecordInternalError(ERR_IPC_WITH_NO_COMMITTED_LOAD); | 621 RecordInternalError(ERR_IPC_WITH_NO_COMMITTED_LOAD); |
497 error = true; | 622 error = true; |
498 } | 623 } |
(...skipping 18 matching lines...) Expand all Loading... | |
517 | 642 |
518 if (!committed_load_->UpdateTiming(timing)) { | 643 if (!committed_load_->UpdateTiming(timing)) { |
519 // If the page load tracker cannot update its timing, something is wrong | 644 // If the page load tracker cannot update its timing, something is wrong |
520 // with the IPC (it's from another load, or it's invalid in some other way). | 645 // with the IPC (it's from another load, or it's invalid in some other way). |
521 // We expect this to be a rare occurrence. | 646 // We expect this to be a rare occurrence. |
522 RecordInternalError(ERR_BAD_TIMING_IPC); | 647 RecordInternalError(ERR_BAD_TIMING_IPC); |
523 } | 648 } |
524 } | 649 } |
525 | 650 |
526 } // namespace page_load_metrics | 651 } // namespace page_load_metrics |
OLD | NEW |