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

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

Issue 2132603002: [page_load_metrics] Add a NavigationThrottle for richer abort metrics (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More browser 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 5009703a5e7ab0b092cd7ceaa59e0657cd4547b3..fc9c4127621560a315b074cb3a202c9bab45a3de 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -261,6 +261,7 @@ PageLoadTracker::PageLoadTracker(
url_(navigation_handle->GetURL()),
abort_type_(ABORT_NONE),
started_in_foreground_(in_foreground),
+ page_transition_(ui::PAGE_TRANSITION_LAST_CORE),
aborted_chain_size_(aborted_chain_size),
aborted_chain_size_same_url_(aborted_chain_size_same_url),
embedder_interface_(embedder_interface) {
@@ -278,11 +279,14 @@ PageLoadTracker::~PageLoadTracker() {
if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) {
RecordInternalError(ERR_NO_IPCS_RECEIVED);
}
- // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
- // chain length added to the next navigation. Take care not to double count
- // them. Also do not double count committed loads, which call this already.
- if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION)
+
+ // Don't include any aborts that resulted in a new navigation, as the chain
+ // length will be included in the aborter PageLoadTracker.
+ if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION &&
+ abort_type_ != ABORT_RELOAD && abort_type_ != ABORT_FORWARD_BACK &&
+ abort_type_ != ABORT_NEW_NAVIGATION) {
LogAbortChainHistograms(nullptr);
+ }
for (const auto& observer : observers_) {
observer->OnComplete(timing_, info);
@@ -383,6 +387,13 @@ void PageLoadTracker::FailedProvisionalLoad(
}
}
+// TODO(csharrison): We can get an approximation of whether the abort is user
Bryan McQuade 2016/07/12 16:45:29 is the intent to record whether it's user initiate
Charlie Harrison 2016/07/12 19:20:22 It isn't necessary to do the browser navigation ch
+// initiated or not from the NavigationHandle at this point.
+void PageLoadTracker::WillStartNavigationRequest(
+ content::NavigationHandle* navigation_handle) {
+ page_transition_ = navigation_handle->GetPageTransition();
+}
+
void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) {
for (const auto& observer : observers_) {
observer->OnRedirect(navigation_handle);
@@ -531,7 +542,8 @@ void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
bool is_certainly_browser_timestamp) {
DCHECK_NE(abort_type, ABORT_NONE);
DCHECK_NE(abort_type, ABORT_OTHER);
- DCHECK_EQ(abort_type_, ABORT_OTHER);
+ DCHECK(abort_type_ == ABORT_OTHER || abort_type_ == ABORT_UNKNOWN_NAVIGATION)
+ << "UpdateAbort called with abort_type_ = " << abort_type_;
// For some aborts (e.g. navigations), the initiated timestamp can be earlier
// than the timestamp that aborted the load. Taking the minimum gives the
@@ -540,11 +552,9 @@ void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
is_certainly_browser_timestamp);
}
-bool PageLoadTracker::IsLikelyProvisionalAbort(
- base::TimeTicks abort_cause_time) {
+bool PageLoadTracker::WasAbortedRecently(base::TimeTicks abort_cause_time) {
// Note that |abort_cause_time - abort_time| can be negative.
- return abort_type_ == ABORT_OTHER &&
- (abort_cause_time - abort_time_).InMilliseconds() < 100;
+ return (abort_cause_time - abort_time_).InMilliseconds() < 100;
}
bool PageLoadTracker::MatchesOriginalNavigation(
@@ -642,6 +652,8 @@ bool MetricsWebContentsObserver::OnMessageReceived(
return handled;
}
+// TODO(csharrison): The only reason DidStartNavigation is needed is for unit
+// tests. Otherwise all this logic can go in WillStartNavigationRequest.
void MetricsWebContentsObserver::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame())
@@ -653,12 +665,10 @@ void MetricsWebContentsObserver::DidStartNavigation(
if (navigation_handle->GetURL().spec().compare(url::kAboutBlankURL) == 0)
return;
- std::unique_ptr<PageLoadTracker> last_aborted =
- NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle);
-
int chain_size_same_url = 0;
int chain_size = 0;
- if (last_aborted) {
+ if (!aborted_provisional_loads_.empty()) {
+ PageLoadTracker* last_aborted = aborted_provisional_loads_.back().get();
if (last_aborted->MatchesOriginalNavigation(navigation_handle)) {
chain_size_same_url = last_aborted->aborted_chain_size_same_url() + 1;
} else if (last_aborted->aborted_chain_size_same_url() > 0) {
@@ -690,11 +700,25 @@ void MetricsWebContentsObserver::DidStartNavigation(
// the MetricsWebContentsObserver owns them both list and they are torn down
// after the PageLoadTracker. The PageLoadTracker does not hold on to
// committed_load_ or navigation_handle beyond the scope of the constructor.
- provisional_loads_.insert(std::make_pair(
+ auto it = provisional_loads_.insert(std::make_pair(
navigation_handle,
base::WrapUnique(new PageLoadTracker(
in_foreground_, embedder_interface_.get(), currently_committed_url,
navigation_handle, chain_size, chain_size_same_url))));
+ // Don't clear the aborted provisional loads here because
+ // WillStartNavigationRequest will soon be called, providing a better value
+ // for the page transition and user gesture.
+ NotifyAbortedProvisionalLoadsNewNavigation(it.first->second.get());
+}
+
+void MetricsWebContentsObserver::WillStartNavigationRequest(
+ content::NavigationHandle* navigation_handle) {
+ auto it = provisional_loads_.find(navigation_handle);
+ if (it == provisional_loads_.end())
+ return;
+ it->second->WillStartNavigationRequest(navigation_handle);
+ NotifyAbortedProvisionalLoadsNewNavigation(it->second.get());
+ aborted_provisional_loads_.clear();
}
const PageLoadExtraInfo
@@ -855,42 +879,49 @@ void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
UserAbortType abort_type,
base::TimeTicks timestamp,
bool is_certainly_browser_timestamp) {
- if (committed_load_)
+ if (committed_load_) {
committed_load_->NotifyAbort(abort_type, timestamp,
+
is_certainly_browser_timestamp);
+ }
for (const auto& kv : provisional_loads_) {
kv.second->NotifyAbort(abort_type, timestamp,
is_certainly_browser_timestamp);
}
for (const auto& tracker : aborted_provisional_loads_) {
- if (tracker->IsLikelyProvisionalAbort(timestamp))
+ // Only update an aborted provisional load if it has an OTHER type. Do not
+ // include UNKNOWN_NAVIGATION here because those are handled in
+ // NotifyAbortedProvisionalLoadsNewNavigation.
+ // TODO(csharrison): This is an implementation flaw due to how the unit
+ // testing framework avoids calling WillStartNavigationRequest.
+ if (tracker->WasAbortedRecently(timestamp) &&
+ tracker->abort_type() == ABORT_OTHER) {
tracker->UpdateAbort(abort_type, timestamp,
is_certainly_browser_timestamp);
+ }
}
aborted_provisional_loads_.clear();
}
-std::unique_ptr<PageLoadTracker>
-MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
- content::NavigationHandle* new_navigation) {
- // If there are multiple aborted loads that can be attributed to this one,
- // just count the latest one for simplicity. Other loads will fall into the
- // OTHER bucket, though there shouldn't be very many.
+void MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
+ PageLoadTracker* new_navigation) {
if (aborted_provisional_loads_.size() == 0)
- return nullptr;
+ return;
if (aborted_provisional_loads_.size() > 1)
RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS);
- std::unique_ptr<PageLoadTracker> last_aborted_load =
- std::move(aborted_provisional_loads_.back());
- aborted_provisional_loads_.pop_back();
-
- base::TimeTicks timestamp = new_navigation->NavigationStart();
- if (last_aborted_load->IsLikelyProvisionalAbort(timestamp))
- last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false);
-
- aborted_provisional_loads_.clear();
- return last_aborted_load;
+ for (const auto& it : aborted_provisional_loads_) {
+ base::TimeTicks timestamp = new_navigation->navigation_start();
+ if (it->WasAbortedRecently(timestamp) &&
+ (it->abort_type() == ABORT_OTHER ||
+ it->abort_type() == ABORT_UNKNOWN_NAVIGATION)) {
+ ui::PageTransition transition = new_navigation->page_transition();
+ UserAbortType abort_type = transition == ui::PAGE_TRANSITION_LAST_CORE
+ ? ABORT_UNKNOWN_NAVIGATION
+ : AbortTypeForPageTransition(transition);
+ it->UpdateAbort(abort_type, timestamp, false);
+ }
+ }
}
void MetricsWebContentsObserver::OnTimingUpdated(

Powered by Google App Engine
This is Rietveld 408576698