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 <algorithm> | 7 #include <algorithm> |
8 #include <ostream> | 8 #include <ostream> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // Helper to allow use of Optional<> values in LOG() messages. | 57 // Helper to allow use of Optional<> values in LOG() messages. |
58 std::ostream& operator<<(std::ostream& os, | 58 std::ostream& operator<<(std::ostream& os, |
59 const base::Optional<base::TimeDelta>& opt) { | 59 const base::Optional<base::TimeDelta>& opt) { |
60 if (opt) | 60 if (opt) |
61 os << opt.value(); | 61 os << opt.value(); |
62 else | 62 else |
63 os << "(unset)"; | 63 os << "(unset)"; |
64 return os; | 64 return os; |
65 } | 65 } |
66 | 66 |
67 // The url we see from the renderer side is not always the same as what | |
68 // we see from the browser side (e.g. chrome://newtab). We want to be | |
69 // sure here that we aren't logging UMA for internal pages. | |
70 bool IsRelevantNavigation(content::NavigationHandle* navigation_handle, | |
71 const GURL& browser_url, | |
72 const std::string& mime_type) { | |
73 DCHECK(navigation_handle->HasCommitted()); | |
74 return navigation_handle->IsInMainFrame() && | |
75 !navigation_handle->IsSamePage() && | |
76 !navigation_handle->IsErrorPage() && | |
77 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && | |
78 browser_url.SchemeIsHTTPOrHTTPS() && | |
79 (mime_type == "text/html" || mime_type == "application/xhtml+xml"); | |
80 } | |
81 | |
82 // If second is non-zero, first must also be non-zero and less than or equal to | 67 // If second is non-zero, first must also be non-zero and less than or equal to |
83 // second. | 68 // second. |
84 bool EventsInOrder(const base::Optional<base::TimeDelta>& first, | 69 bool EventsInOrder(const base::Optional<base::TimeDelta>& first, |
85 const base::Optional<base::TimeDelta>& second) { | 70 const base::Optional<base::TimeDelta>& second) { |
86 if (!second) { | 71 if (!second) { |
87 return true; | 72 return true; |
88 } | 73 } |
89 return first && first <= second; | 74 return first && first <= second; |
90 } | 75 } |
91 | 76 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL, | 201 UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL, |
217 aborted_chain_size_same_url); | 202 aborted_chain_size_same_url); |
218 } | 203 } |
219 } | 204 } |
220 | 205 |
221 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, | 206 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, |
222 const PageLoadTiming& last_timing, | 207 const PageLoadTiming& last_timing, |
223 const PageLoadTiming& new_timing, | 208 const PageLoadTiming& new_timing, |
224 const PageLoadMetadata& last_metadata, | 209 const PageLoadMetadata& last_metadata, |
225 const PageLoadExtraInfo& extra_info) { | 210 const PageLoadExtraInfo& extra_info) { |
226 observer->OnTimingUpdate(new_timing, extra_info); | 211 if (last_timing != new_timing) |
| 212 observer->OnTimingUpdate(new_timing, extra_info); |
227 if (new_timing.dom_content_loaded_event_start && | 213 if (new_timing.dom_content_loaded_event_start && |
228 !last_timing.dom_content_loaded_event_start) | 214 !last_timing.dom_content_loaded_event_start) |
229 observer->OnDomContentLoadedEventStart(new_timing, extra_info); | 215 observer->OnDomContentLoadedEventStart(new_timing, extra_info); |
230 if (new_timing.load_event_start && !last_timing.load_event_start) | 216 if (new_timing.load_event_start && !last_timing.load_event_start) |
231 observer->OnLoadEventStart(new_timing, extra_info); | 217 observer->OnLoadEventStart(new_timing, extra_info); |
232 if (new_timing.first_layout && !last_timing.first_layout) | 218 if (new_timing.first_layout && !last_timing.first_layout) |
233 observer->OnFirstLayout(new_timing, extra_info); | 219 observer->OnFirstLayout(new_timing, extra_info); |
234 if (new_timing.first_paint && !last_timing.first_paint) | 220 if (new_timing.first_paint && !last_timing.first_paint) |
235 observer->OnFirstPaint(new_timing, extra_info); | 221 observer->OnFirstPaint(new_timing, extra_info); |
236 if (new_timing.first_text_paint && !last_timing.first_text_paint) | 222 if (new_timing.first_text_paint && !last_timing.first_text_paint) |
(...skipping 12 matching lines...) Expand all Loading... |
249 | 235 |
250 } // namespace | 236 } // namespace |
251 | 237 |
252 PageLoadTracker::PageLoadTracker( | 238 PageLoadTracker::PageLoadTracker( |
253 bool in_foreground, | 239 bool in_foreground, |
254 PageLoadMetricsEmbedderInterface* embedder_interface, | 240 PageLoadMetricsEmbedderInterface* embedder_interface, |
255 const GURL& currently_committed_url, | 241 const GURL& currently_committed_url, |
256 content::NavigationHandle* navigation_handle, | 242 content::NavigationHandle* navigation_handle, |
257 int aborted_chain_size, | 243 int aborted_chain_size, |
258 int aborted_chain_size_same_url) | 244 int aborted_chain_size_same_url) |
259 : renderer_tracked_(false), | 245 : did_stop_tracking_(false), |
260 navigation_start_(navigation_handle->NavigationStart()), | 246 navigation_start_(navigation_handle->NavigationStart()), |
261 url_(navigation_handle->GetURL()), | 247 url_(navigation_handle->GetURL()), |
262 abort_type_(ABORT_NONE), | 248 abort_type_(ABORT_NONE), |
263 started_in_foreground_(in_foreground), | 249 started_in_foreground_(in_foreground), |
264 aborted_chain_size_(aborted_chain_size), | 250 aborted_chain_size_(aborted_chain_size), |
265 aborted_chain_size_same_url_(aborted_chain_size_same_url), | 251 aborted_chain_size_same_url_(aborted_chain_size_same_url), |
266 embedder_interface_(embedder_interface) { | 252 embedder_interface_(embedder_interface) { |
267 DCHECK(!navigation_handle->HasCommitted()); | 253 DCHECK(!navigation_handle->HasCommitted()); |
268 embedder_interface_->RegisterObservers(this); | 254 embedder_interface_->RegisterObservers(this); |
269 for (const auto& observer : observers_) { | 255 for (const auto& observer : observers_) { |
270 observer->OnStart(navigation_handle, currently_committed_url, | 256 observer->OnStart(navigation_handle, currently_committed_url, |
271 started_in_foreground_); | 257 started_in_foreground_); |
272 } | 258 } |
273 } | 259 } |
274 | 260 |
275 PageLoadTracker::~PageLoadTracker() { | 261 PageLoadTracker::~PageLoadTracker() { |
| 262 if (did_stop_tracking_) |
| 263 return; |
| 264 |
276 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); | 265 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); |
277 | 266 |
278 if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) { | 267 if (info.time_to_commit && timing_.IsEmpty()) { |
279 RecordInternalError(ERR_NO_IPCS_RECEIVED); | 268 RecordInternalError(ERR_NO_IPCS_RECEIVED); |
280 } | 269 } |
281 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their | 270 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their |
282 // chain length added to the next navigation. Take care not to double count | 271 // chain length added to the next navigation. Take care not to double count |
283 // them. Also do not double count committed loads, which call this already. | 272 // them. Also do not double count committed loads, which call this already. |
284 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) | 273 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) |
285 LogAbortChainHistograms(nullptr); | 274 LogAbortChainHistograms(nullptr); |
286 | 275 |
287 for (const auto& observer : observers_) { | 276 for (const auto& observer : observers_) { |
288 observer->OnComplete(timing_, info); | 277 observer->OnComplete(timing_, info); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); | 427 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); |
439 for (const auto& observer : observers_) { | 428 for (const auto& observer : observers_) { |
440 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, | 429 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, |
441 last_metadata, info); | 430 last_metadata, info); |
442 } | 431 } |
443 return true; | 432 return true; |
444 } | 433 } |
445 return false; | 434 return false; |
446 } | 435 } |
447 | 436 |
448 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) { | 437 void PageLoadTracker::StopTracking() { |
449 renderer_tracked_ = renderer_tracked; | 438 did_stop_tracking_ = true; |
450 } | 439 } |
451 | 440 |
452 void PageLoadTracker::AddObserver( | 441 void PageLoadTracker::AddObserver( |
453 std::unique_ptr<PageLoadMetricsObserver> observer) { | 442 std::unique_ptr<PageLoadMetricsObserver> observer) { |
454 observers_.push_back(std::move(observer)); | 443 observers_.push_back(std::move(observer)); |
455 } | 444 } |
456 | 445 |
457 void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew( | 446 void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew( |
458 base::TimeTicks* event_time) { | 447 base::TimeTicks* event_time) { |
459 DCHECK(event_time != nullptr); | 448 DCHECK(event_time != nullptr); |
460 // Windows 10 GCE bot non-deterministically failed because TimeTicks::Now() | 449 // Windows 10 GCE bot non-deterministically failed because TimeTicks::Now() |
461 // called in the browser process e.g. commit_time was less than | 450 // called in the browser process e.g. commit_time was less than |
462 // navigation_start_ that was populated in the renderer process because the | 451 // navigation_start_ that was populated in the renderer process because the |
463 // clock was not system-wide monotonic. | 452 // clock was not system-wide monotonic. |
464 // Note that navigation_start_ can also be set in the browser process in | 453 // Note that navigation_start_ can also be set in the browser process in |
465 // some cases and in those cases event_time should never be < | 454 // some cases and in those cases event_time should never be < |
466 // navigation_start_. If it is due to a code error and it gets clamped in this | 455 // navigation_start_. If it is due to a code error and it gets clamped in this |
467 // function, on high resolution systems it should lead to a dcheck failure. | 456 // function, on high resolution systems it should lead to a dcheck failure. |
468 | 457 |
469 // TODO (shivanisha) Currently IsHighResolution is the best way to check | 458 // TODO(shivanisha): Currently IsHighResolution is the best way to check |
470 // if the clock is system-wide monotonic. However IsHighResolution | 459 // if the clock is system-wide monotonic. However IsHighResolution |
471 // does a broader check to see if the clock in use is high resolution | 460 // does a broader check to see if the clock in use is high resolution |
472 // which also implies it is system-wide monotonic (on Windows). | 461 // which also implies it is system-wide monotonic (on Windows). |
473 if (base::TimeTicks::IsHighResolution()) { | 462 if (base::TimeTicks::IsHighResolution()) { |
474 DCHECK(event_time->is_null() || *event_time >= navigation_start_); | 463 DCHECK(event_time->is_null() || *event_time >= navigation_start_); |
475 return; | 464 return; |
476 } | 465 } |
477 | 466 |
478 if (!event_time->is_null() && *event_time < navigation_start_) { | 467 if (!event_time->is_null() && *event_time < navigation_start_) { |
479 RecordInternalError(ERR_INTER_PROCESS_TIME_TICK_SKEW); | 468 RecordInternalError(ERR_INTER_PROCESS_TIME_TICK_SKEW); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) | 628 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) |
640 IPC_MESSAGE_UNHANDLED(handled = false) | 629 IPC_MESSAGE_UNHANDLED(handled = false) |
641 IPC_END_MESSAGE_MAP() | 630 IPC_END_MESSAGE_MAP() |
642 return handled; | 631 return handled; |
643 } | 632 } |
644 | 633 |
645 void MetricsWebContentsObserver::DidStartNavigation( | 634 void MetricsWebContentsObserver::DidStartNavigation( |
646 content::NavigationHandle* navigation_handle) { | 635 content::NavigationHandle* navigation_handle) { |
647 if (!navigation_handle->IsInMainFrame()) | 636 if (!navigation_handle->IsInMainFrame()) |
648 return; | 637 return; |
649 if (embedder_interface_->IsPrerendering(web_contents())) | |
650 return; | |
651 if (embedder_interface_->IsNewTabPageUrl(navigation_handle->GetURL())) | |
652 return; | |
653 if (navigation_handle->GetURL().spec().compare(url::kAboutBlankURL) == 0) | |
654 return; | |
655 | 638 |
656 std::unique_ptr<PageLoadTracker> last_aborted = | 639 std::unique_ptr<PageLoadTracker> last_aborted = |
657 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle); | 640 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle); |
658 | 641 |
659 int chain_size_same_url = 0; | 642 int chain_size_same_url = 0; |
660 int chain_size = 0; | 643 int chain_size = 0; |
661 if (last_aborted) { | 644 if (last_aborted) { |
662 if (last_aborted->MatchesOriginalNavigation(navigation_handle)) { | 645 if (last_aborted->MatchesOriginalNavigation(navigation_handle)) { |
663 chain_size_same_url = last_aborted->aborted_chain_size_same_url() + 1; | 646 chain_size_same_url = last_aborted->aborted_chain_size_same_url() + 1; |
664 } else if (last_aborted->aborted_chain_size_same_url() > 0) { | 647 } else if (last_aborted->aborted_chain_size_same_url() > 0) { |
665 LogAbortChainSameURLHistogram( | 648 LogAbortChainSameURLHistogram( |
666 last_aborted->aborted_chain_size_same_url()); | 649 last_aborted->aborted_chain_size_same_url()); |
667 } | 650 } |
668 chain_size = last_aborted->aborted_chain_size() + 1; | 651 chain_size = last_aborted->aborted_chain_size() + 1; |
669 } | 652 } |
670 | 653 |
| 654 if (!ShouldTrackNavigation(navigation_handle)) |
| 655 return; |
| 656 |
| 657 // TODO(bmcquade): add support for tracking prerendered pages when they become |
| 658 // visible. |
| 659 if (embedder_interface_->IsPrerendering(web_contents())) |
| 660 return; |
| 661 |
671 // Pass in the last committed url to the PageLoadTracker. If the MWCO has | 662 // Pass in the last committed url to the PageLoadTracker. If the MWCO has |
672 // never observed a committed load, use the last committed url from this | 663 // never observed a committed load, use the last committed url from this |
673 // WebContent's opener. This is more accurate than using referrers due to | 664 // WebContent's opener. This is more accurate than using referrers due to |
674 // referrer sanitizing and origin referrers. Note that this could potentially | 665 // referrer sanitizing and origin referrers. Note that this could potentially |
675 // be inaccurate if the opener has since navigated. | 666 // be inaccurate if the opener has since navigated. |
676 content::WebContents* opener = web_contents()->GetOpener(); | 667 content::WebContents* opener = web_contents()->GetOpener(); |
677 const GURL& opener_url = | 668 const GURL& opener_url = |
678 !has_navigated_ && opener | 669 !has_navigated_ && opener |
679 ? web_contents()->GetOpener()->GetLastCommittedURL() | 670 ? web_contents()->GetOpener()->GetLastCommittedURL() |
680 : GURL::EmptyGURL(); | 671 : GURL::EmptyGURL(); |
(...skipping 24 matching lines...) Expand all Loading... |
705 | 696 |
706 void MetricsWebContentsObserver::DidFinishNavigation( | 697 void MetricsWebContentsObserver::DidFinishNavigation( |
707 content::NavigationHandle* navigation_handle) { | 698 content::NavigationHandle* navigation_handle) { |
708 if (!navigation_handle->IsInMainFrame()) | 699 if (!navigation_handle->IsInMainFrame()) |
709 return; | 700 return; |
710 | 701 |
711 std::unique_ptr<PageLoadTracker> finished_nav( | 702 std::unique_ptr<PageLoadTracker> finished_nav( |
712 std::move(provisional_loads_[navigation_handle])); | 703 std::move(provisional_loads_[navigation_handle])); |
713 provisional_loads_.erase(navigation_handle); | 704 provisional_loads_.erase(navigation_handle); |
714 | 705 |
715 // There's a chance a navigation could have started before we were added to a | 706 const bool should_track = |
716 // tab. Bail out early if this is the case. | 707 finished_nav && ShouldTrackNavigation(navigation_handle); |
717 if (!finished_nav) | |
718 return; | |
719 | 708 |
720 // Handle a pre-commit error here. Navigations that result in an error page | 709 if (finished_nav && !should_track) |
721 // will be ignored. Note that downloads/204s will result in HasCommitted() | 710 finished_nav->StopTracking(); |
722 // returning false. | |
723 // TODO(csharrison): Track changes to NavigationHandle for signals when this | |
724 // is the case (HTTP response headers). | |
725 if (!navigation_handle->HasCommitted()) { | |
726 finished_nav->FailedProvisionalLoad(navigation_handle); | |
727 | 711 |
728 net::Error error = navigation_handle->GetNetErrorCode(); | 712 if (navigation_handle->HasCommitted()) { |
| 713 // Ignore same-page navigations. |
| 714 if (navigation_handle->IsSamePage()) |
| 715 return; |
729 | 716 |
730 // net::OK: This case occurs when the NavigationHandle finishes and reports | 717 // Notify other loads that they may have been aborted by this committed |
731 // !HasCommitted(), but reports no net::Error. This should not occur | 718 // load. Note that by using the committed navigation start as the abort |
732 // pre-PlzNavigate, but afterwards it should represent the navigation | 719 // cause, we lose data on provisional loads that were aborted by other |
733 // stopped by the user before it was ready to commit. | 720 // provisional loads. Those will either be listed as ABORT_OTHER or as being |
734 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED. | 721 // aborted by this load. |
735 // Note that this can come from some non user-initiated errors, such as | 722 // is_certainly_browser_timestamp is set to false because NavigationStart() |
736 // downloads, or 204 responses. See crbug.com/542369. | 723 // could be set in either the renderer or browser process. |
737 if ((error == net::OK) || (error == net::ERR_ABORTED)) { | 724 NotifyAbortAllLoadsWithTimestamp( |
738 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true); | 725 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), |
739 aborted_provisional_loads_.push_back(std::move(finished_nav)); | 726 navigation_handle->NavigationStart(), false); |
| 727 |
| 728 if (should_track) { |
| 729 HandleCommittedNavigationForTrackedLoad(navigation_handle, |
| 730 std::move(finished_nav)); |
| 731 } else { |
| 732 committed_load_.reset(); |
740 } | 733 } |
| 734 } else if (should_track) { |
| 735 HandleFailedNavigationForTrackedLoad(navigation_handle, |
| 736 std::move(finished_nav)); |
| 737 } |
| 738 } |
741 | 739 |
742 return; | 740 // Handle a pre-commit error. Navigations that result in an error page will be |
| 741 // ignored. Note that downloads/204s will result in HasCommitted() returning |
| 742 // false. |
| 743 // TODO(csharrison): Track changes to NavigationHandle for signals when this is |
| 744 // the case (HTTP response headers). |
| 745 void MetricsWebContentsObserver::HandleFailedNavigationForTrackedLoad( |
| 746 content::NavigationHandle* navigation_handle, |
| 747 std::unique_ptr<PageLoadTracker> tracker) { |
| 748 tracker->FailedProvisionalLoad(navigation_handle); |
| 749 |
| 750 net::Error error = navigation_handle->GetNetErrorCode(); |
| 751 |
| 752 // net::OK: This case occurs when the NavigationHandle finishes and reports |
| 753 // !HasCommitted(), but reports no net::Error. This should not occur |
| 754 // pre-PlzNavigate, but afterwards it should represent the navigation stopped |
| 755 // by the user before it was ready to commit. |
| 756 // net::ERR_ABORTED: An aborted provisional load has error |
| 757 // net::ERR_ABORTED. Note that this can come from some non user-initiated |
| 758 // errors, such as downloads, or 204 responses. See crbug.com/542369. |
| 759 if ((error == net::OK) || (error == net::ERR_ABORTED)) { |
| 760 tracker->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true); |
| 761 aborted_provisional_loads_.push_back(std::move(tracker)); |
743 } | 762 } |
| 763 } |
744 | 764 |
745 // Don't treat a same-page nav as a new page load. | 765 void MetricsWebContentsObserver::HandleCommittedNavigationForTrackedLoad( |
746 if (navigation_handle->IsSamePage()) | 766 content::NavigationHandle* navigation_handle, |
747 return; | 767 std::unique_ptr<PageLoadTracker> tracker) { |
748 | |
749 if (!navigation_handle->HasUserGesture() && | 768 if (!navigation_handle->HasUserGesture() && |
750 (navigation_handle->GetPageTransition() & | 769 (navigation_handle->GetPageTransition() & |
751 ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0 && | 770 ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0 && |
752 committed_load_) | 771 committed_load_) |
753 committed_load_->NotifyClientRedirectTo(*finished_nav); | 772 committed_load_->NotifyClientRedirectTo(*tracker); |
754 | 773 |
755 // Notify other loads that they may have been aborted by this committed load. | 774 committed_load_ = std::move(tracker); |
756 // Note that by using the committed navigation start as the abort cause, we | |
757 // lose data on provisional loads that were aborted by other provisional | |
758 // loads. Those will either be listed as ABORT_OTHER or as being aborted by | |
759 // this load. | |
760 // is_certainly_browser_timestamp is set to false because NavigationStart() | |
761 // could be set in either the renderer or browser process. | |
762 NotifyAbortAllLoadsWithTimestamp( | |
763 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), | |
764 navigation_handle->NavigationStart(), false); | |
765 | |
766 committed_load_ = std::move(finished_nav); | |
767 aborted_provisional_loads_.clear(); | |
768 | |
769 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | |
770 const std::string& mime_type = web_contents()->GetContentsMimeType(); | |
771 DCHECK(!browser_url.is_empty()); | |
772 DCHECK(!mime_type.empty()); | |
773 committed_load_->set_renderer_tracked( | |
774 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); | |
775 | |
776 committed_load_->Commit(navigation_handle); | 775 committed_load_->Commit(navigation_handle); |
777 } | 776 } |
778 | 777 |
779 void MetricsWebContentsObserver::NavigationStopped() { | 778 void MetricsWebContentsObserver::NavigationStopped() { |
780 NotifyAbortAllLoads(ABORT_STOP); | 779 NotifyAbortAllLoads(ABORT_STOP); |
781 } | 780 } |
782 | 781 |
783 void MetricsWebContentsObserver::OnInputEvent( | 782 void MetricsWebContentsObserver::OnInputEvent( |
784 const blink::WebInputEvent& event) { | 783 const blink::WebInputEvent& event) { |
785 // Ignore browser navigation or reload which comes with type Undefined. | 784 // Ignore browser navigation or reload which comes with type Undefined. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 | 886 |
888 aborted_provisional_loads_.clear(); | 887 aborted_provisional_loads_.clear(); |
889 return last_aborted_load; | 888 return last_aborted_load; |
890 } | 889 } |
891 | 890 |
892 void MetricsWebContentsObserver::OnTimingUpdated( | 891 void MetricsWebContentsObserver::OnTimingUpdated( |
893 content::RenderFrameHost* render_frame_host, | 892 content::RenderFrameHost* render_frame_host, |
894 const PageLoadTiming& timing, | 893 const PageLoadTiming& timing, |
895 const PageLoadMetadata& metadata) { | 894 const PageLoadMetadata& metadata) { |
896 bool error = false; | 895 bool error = false; |
897 if (!committed_load_ || !committed_load_->renderer_tracked()) { | 896 if (!committed_load_) { |
898 RecordInternalError(ERR_IPC_WITH_NO_RELEVANT_LOAD); | 897 RecordInternalError(ERR_IPC_WITH_NO_RELEVANT_LOAD); |
899 error = true; | 898 error = true; |
900 } | 899 } |
901 | 900 |
902 // We may receive notifications from frames that have been navigated away | 901 // We may receive notifications from frames that have been navigated away |
903 // from. We simply ignore them. | 902 // from. We simply ignore them. |
904 if (render_frame_host != web_contents()->GetMainFrame()) { | 903 if (render_frame_host != web_contents()->GetMainFrame()) { |
905 RecordInternalError(ERR_IPC_FROM_WRONG_FRAME); | 904 RecordInternalError(ERR_IPC_FROM_WRONG_FRAME); |
906 error = true; | 905 error = true; |
907 } | 906 } |
(...skipping 10 matching lines...) Expand all Loading... |
918 return; | 917 return; |
919 | 918 |
920 if (!committed_load_->UpdateTiming(timing, metadata)) { | 919 if (!committed_load_->UpdateTiming(timing, metadata)) { |
921 // If the page load tracker cannot update its timing, something is wrong | 920 // If the page load tracker cannot update its timing, something is wrong |
922 // with the IPC (it's from another load, or it's invalid in some other way). | 921 // with the IPC (it's from another load, or it's invalid in some other way). |
923 // We expect this to be a rare occurrence. | 922 // We expect this to be a rare occurrence. |
924 RecordInternalError(ERR_BAD_TIMING_IPC); | 923 RecordInternalError(ERR_BAD_TIMING_IPC); |
925 } | 924 } |
926 } | 925 } |
927 | 926 |
| 927 bool MetricsWebContentsObserver::ShouldTrackNavigation( |
| 928 content::NavigationHandle* navigation_handle) const { |
| 929 DCHECK(navigation_handle->IsInMainFrame()); |
| 930 if (!navigation_handle->GetURL().SchemeIsHTTPOrHTTPS()) |
| 931 return false; |
| 932 if (embedder_interface_->IsNewTabPageUrl(navigation_handle->GetURL())) |
| 933 return false; |
| 934 if (navigation_handle->HasCommitted()) { |
| 935 if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage()) |
| 936 return false; |
| 937 const std::string& mime_type = web_contents()->GetContentsMimeType(); |
| 938 if (mime_type != "text/html" && mime_type != "application/xhtml+xml") |
| 939 return false; |
| 940 } |
| 941 return true; |
| 942 } |
| 943 |
928 } // namespace page_load_metrics | 944 } // namespace page_load_metrics |
OLD | NEW |