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

Unified Diff: components/page_load_metrics/browser/metrics_web_contents_observer.cc

Issue 2139143002: Standardize which page loads are tracked (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add tests Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: components/page_load_metrics/browser/metrics_web_contents_observer.cc
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index c9896b7d5e9aaa7fe08705a332477d05175d29cf..5039557a870d9105b727da9e2eddc1834b170424 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -64,21 +64,6 @@ std::ostream& operator<<(std::ostream& os,
return os;
}
-// The url we see from the renderer side is not always the same as what
-// we see from the browser side (e.g. chrome://newtab). We want to be
-// sure here that we aren't logging UMA for internal pages.
-bool IsRelevantNavigation(content::NavigationHandle* navigation_handle,
- const GURL& browser_url,
- const std::string& mime_type) {
- DCHECK(navigation_handle->HasCommitted());
- return navigation_handle->IsInMainFrame() &&
- !navigation_handle->IsSamePage() &&
- !navigation_handle->IsErrorPage() &&
- navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() &&
- browser_url.SchemeIsHTTPOrHTTPS() &&
- (mime_type == "text/html" || mime_type == "application/xhtml+xml");
-}
-
// If second is non-zero, first must also be non-zero and less than or equal to
// second.
bool EventsInOrder(const base::Optional<base::TimeDelta>& first,
@@ -223,7 +208,8 @@ void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer,
const PageLoadTiming& new_timing,
const PageLoadMetadata& last_metadata,
const PageLoadExtraInfo& extra_info) {
- observer->OnTimingUpdate(new_timing, extra_info);
+ if (last_timing != new_timing)
+ observer->OnTimingUpdate(new_timing, extra_info);
if (new_timing.dom_content_loaded_event_start &&
!last_timing.dom_content_loaded_event_start)
observer->OnDomContentLoadedEventStart(new_timing, extra_info);
@@ -256,7 +242,7 @@ PageLoadTracker::PageLoadTracker(
content::NavigationHandle* navigation_handle,
int aborted_chain_size,
int aborted_chain_size_same_url)
- : renderer_tracked_(false),
+ : did_stop_tracking_(false),
navigation_start_(navigation_handle->NavigationStart()),
url_(navigation_handle->GetURL()),
abort_type_(ABORT_NONE),
@@ -273,9 +259,12 @@ PageLoadTracker::PageLoadTracker(
}
PageLoadTracker::~PageLoadTracker() {
+ if (did_stop_tracking_)
+ return;
+
const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
- if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) {
+ if (info.time_to_commit && timing_.IsEmpty()) {
RecordInternalError(ERR_NO_IPCS_RECEIVED);
}
// Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
@@ -445,8 +434,8 @@ bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing,
return false;
}
-void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) {
- renderer_tracked_ = renderer_tracked;
+void PageLoadTracker::StopTracking() {
+ did_stop_tracking_ = true;
}
void PageLoadTracker::AddObserver(
@@ -466,7 +455,7 @@ void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew(
// navigation_start_. If it is due to a code error and it gets clamped in this
// function, on high resolution systems it should lead to a dcheck failure.
- // TODO (shivanisha) Currently IsHighResolution is the best way to check
+ // TODO(shivanisha): Currently IsHighResolution is the best way to check
// if the clock is system-wide monotonic. However IsHighResolution
// does a broader check to see if the clock in use is high resolution
// which also implies it is system-wide monotonic (on Windows).
@@ -646,12 +635,6 @@ void MetricsWebContentsObserver::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame())
return;
- if (embedder_interface_->IsPrerendering(web_contents()))
- return;
- if (embedder_interface_->IsNewTabPageUrl(navigation_handle->GetURL()))
- return;
- if (navigation_handle->GetURL().spec().compare(url::kAboutBlankURL) == 0)
- return;
std::unique_ptr<PageLoadTracker> last_aborted =
NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle);
@@ -668,6 +651,14 @@ void MetricsWebContentsObserver::DidStartNavigation(
chain_size = last_aborted->aborted_chain_size() + 1;
}
+ if (!ShouldTrackNavigation(navigation_handle))
+ return;
+
+ // TODO(bmcquade): add support for tracking prerendered pages when they become
+ // visible.
+ if (embedder_interface_->IsPrerendering(web_contents()))
+ return;
+
// Pass in the last committed url to the PageLoadTracker. If the MWCO has
// never observed a committed load, use the last committed url from this
// WebContent's opener. This is more accurate than using referrers due to
@@ -712,67 +703,75 @@ void MetricsWebContentsObserver::DidFinishNavigation(
std::move(provisional_loads_[navigation_handle]));
provisional_loads_.erase(navigation_handle);
- // There's a chance a navigation could have started before we were added to a
- // tab. Bail out early if this is the case.
- if (!finished_nav)
- return;
+ const bool should_track =
+ finished_nav && ShouldTrackNavigation(navigation_handle);
- // Handle a pre-commit error here. Navigations that result in an error page
- // will be ignored. Note that downloads/204s will result in HasCommitted()
- // returning false.
- // TODO(csharrison): Track changes to NavigationHandle for signals when this
- // is the case (HTTP response headers).
- if (!navigation_handle->HasCommitted()) {
- finished_nav->FailedProvisionalLoad(navigation_handle);
-
- net::Error error = navigation_handle->GetNetErrorCode();
-
- // net::OK: This case occurs when the NavigationHandle finishes and reports
- // !HasCommitted(), but reports no net::Error. This should not occur
- // pre-PlzNavigate, but afterwards it should represent the navigation
- // stopped by the user before it was ready to commit.
- // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED.
- // Note that this can come from some non user-initiated errors, such as
- // downloads, or 204 responses. See crbug.com/542369.
- if ((error == net::OK) || (error == net::ERR_ABORTED)) {
- finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true);
- aborted_provisional_loads_.push_back(std::move(finished_nav));
- }
+ if (finished_nav && !should_track)
+ finished_nav->StopTracking();
- return;
+ if (navigation_handle->HasCommitted()) {
+ // Ignore same-page navigations.
+ if (navigation_handle->IsSamePage())
+ return;
+
+ // Notify other loads that they may have been aborted by this committed
+ // load. Note that by using the committed navigation start as the abort
+ // cause, we lose data on provisional loads that were aborted by other
+ // provisional loads. Those will either be listed as ABORT_OTHER or as being
+ // aborted by this load.
+ // is_certainly_browser_timestamp is set to false because NavigationStart()
+ // could be set in either the renderer or browser process.
+ NotifyAbortAllLoadsWithTimestamp(
+ AbortTypeForPageTransition(navigation_handle->GetPageTransition()),
+ navigation_handle->NavigationStart(), false);
+
+ if (should_track) {
+ HandleCommittedNavigationForTrackedLoad(navigation_handle,
+ std::move(finished_nav));
+ } else {
+ committed_load_.reset();
+ }
+ } else if (should_track) {
+ HandleFailedNavigationForTrackedLoad(navigation_handle,
+ std::move(finished_nav));
}
+}
- // Don't treat a same-page nav as a new page load.
- if (navigation_handle->IsSamePage())
- return;
+// Handle a pre-commit error. Navigations that result in an error page will be
+// ignored. Note that downloads/204s will result in HasCommitted() returning
+// false.
+// TODO(csharrison): Track changes to NavigationHandle for signals when this is
+// the case (HTTP response headers).
+void MetricsWebContentsObserver::HandleFailedNavigationForTrackedLoad(
+ content::NavigationHandle* navigation_handle,
+ std::unique_ptr<PageLoadTracker> tracker) {
+ tracker->FailedProvisionalLoad(navigation_handle);
+
+ net::Error error = navigation_handle->GetNetErrorCode();
+
+ // net::OK: This case occurs when the NavigationHandle finishes and reports
+ // !HasCommitted(), but reports no net::Error. This should not occur
+ // pre-PlzNavigate, but afterwards it should represent the navigation stopped
+ // by the user before it was ready to commit.
+ // net::ERR_ABORTED: An aborted provisional load has error
+ // net::ERR_ABORTED. Note that this can come from some non user-initiated
+ // errors, such as downloads, or 204 responses. See crbug.com/542369.
+ if ((error == net::OK) || (error == net::ERR_ABORTED)) {
+ tracker->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true);
+ aborted_provisional_loads_.push_back(std::move(tracker));
+ }
+}
+void MetricsWebContentsObserver::HandleCommittedNavigationForTrackedLoad(
+ content::NavigationHandle* navigation_handle,
+ std::unique_ptr<PageLoadTracker> tracker) {
if (!navigation_handle->HasUserGesture() &&
(navigation_handle->GetPageTransition() &
ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0 &&
committed_load_)
- committed_load_->NotifyClientRedirectTo(*finished_nav);
-
- // Notify other loads that they may have been aborted by this committed load.
- // Note that by using the committed navigation start as the abort cause, we
- // lose data on provisional loads that were aborted by other provisional
- // loads. Those will either be listed as ABORT_OTHER or as being aborted by
- // this load.
- // is_certainly_browser_timestamp is set to false because NavigationStart()
- // could be set in either the renderer or browser process.
- NotifyAbortAllLoadsWithTimestamp(
- AbortTypeForPageTransition(navigation_handle->GetPageTransition()),
- navigation_handle->NavigationStart(), false);
-
- committed_load_ = std::move(finished_nav);
- aborted_provisional_loads_.clear();
-
- const GURL& browser_url = web_contents()->GetLastCommittedURL();
- const std::string& mime_type = web_contents()->GetContentsMimeType();
- DCHECK(!browser_url.is_empty());
- DCHECK(!mime_type.empty());
- committed_load_->set_renderer_tracked(
- IsRelevantNavigation(navigation_handle, browser_url, mime_type));
+ committed_load_->NotifyClientRedirectTo(*tracker);
+ committed_load_ = std::move(tracker);
committed_load_->Commit(navigation_handle);
}
@@ -894,7 +893,7 @@ void MetricsWebContentsObserver::OnTimingUpdated(
const PageLoadTiming& timing,
const PageLoadMetadata& metadata) {
bool error = false;
- if (!committed_load_ || !committed_load_->renderer_tracked()) {
+ if (!committed_load_) {
RecordInternalError(ERR_IPC_WITH_NO_RELEVANT_LOAD);
error = true;
}
@@ -925,4 +924,21 @@ void MetricsWebContentsObserver::OnTimingUpdated(
}
}
+bool MetricsWebContentsObserver::ShouldTrackNavigation(
+ content::NavigationHandle* navigation_handle) const {
+ DCHECK(navigation_handle->IsInMainFrame());
+ if (!navigation_handle->GetURL().SchemeIsHTTPOrHTTPS())
+ return false;
+ if (embedder_interface_->IsNewTabPageUrl(navigation_handle->GetURL()))
+ return false;
+ if (navigation_handle->HasCommitted()) {
+ if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage())
+ return false;
+ const std::string& mime_type = web_contents()->GetContentsMimeType();
+ if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
+ return false;
+ }
+ return true;
+}
+
} // namespace page_load_metrics

Powered by Google App Engine
This is Rietveld 408576698