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 df37a05170039af3a2dc72aef32bfb39e3572255..7452e406d3b92cabf1c8a1836d74701676ebc3d0 100644 |
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc |
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc |
@@ -64,42 +64,46 @@ base::Time WallTimeFromTimeTicks(base::TimeTicks time) { |
base::TimeDelta::FromMinutes(10), 100) |
PageLoadTracker::PageLoadTracker(bool in_foreground) |
- : has_commit_(false), started_in_foreground_(in_foreground) { |
- RecordEvent(PAGE_LOAD_STARTED); |
-} |
+ : has_commit_(false), started_in_foreground_(in_foreground) {} |
PageLoadTracker::~PageLoadTracker() { |
- // Even a load that failed a provisional load should log |
- // that it aborted before first layout. |
- if (timing_.first_layout.is_zero()) |
- RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); |
- |
if (has_commit_) |
RecordTimingHistograms(); |
} |
void PageLoadTracker::WebContentsHidden() { |
// Only log the first time we background in a given page load. |
- if (background_time_.is_null()) { |
+ if (started_in_foreground_ && background_time_.is_null()) |
background_time_ = base::TimeTicks::Now(); |
- } |
+} |
+ |
+void PageLoadTracker::WebContentsShown() { |
+ // Only log the first time we foreground in a given page load. |
+ // Don't log foreground time if we started foregrounded. |
+ if (!started_in_foreground_ && foreground_time_.is_null()) |
+ foreground_time_ = base::TimeTicks::Now(); |
} |
void PageLoadTracker::Commit() { |
has_commit_ = true; |
+ if (started_in_foreground_) |
+ RecordCommittedEvent(COMMITTED_LOAD_STARTED_IN_FOREGROUND); |
+ else |
+ RecordCommittedEvent(COMMITTED_LOAD_STARTED_IN_BACKGROUND); |
} |
-bool PageLoadTracker::UpdateTiming(const PageLoadTiming& timing) { |
+bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing) { |
// Throw away IPCs that are not relevant to the current navigation. |
- if (!timing_.navigation_start.is_null() && |
- timing_.navigation_start != timing.navigation_start) { |
- // TODO(csharrison) uma log a counter here |
- return false; |
- } |
- if (IsValidPageLoadTiming(timing)) { |
- timing_ = timing; |
+ // A valid timing struct is one that has the same navigation start as the |
+ // previous one (if the previous one had a navigation start at all). |
+ bool valid_timing_descendent = |
+ timing_.navigation_start.is_null() || |
+ timing_.navigation_start == new_timing.navigation_start; |
+ if (IsValidPageLoadTiming(new_timing) && valid_timing_descendent) { |
+ timing_ = new_timing; |
return true; |
} |
+ RecordCommittedEvent(COMMITTED_LOAD_BAD_IPC); |
return false; |
} |
@@ -135,23 +139,39 @@ void PageLoadTracker::RecordTimingHistograms() { |
timing_.load_event_start); |
} |
} |
- if (!timing_.first_layout.is_zero()) { |
+ if (timing_.first_layout.is_zero()) { |
+ RecordCommittedEvent(COMMITTED_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); |
+ } else { |
if (timing_.first_layout < background_delta) { |
PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", |
timing_.first_layout); |
- RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); |
+ RecordCommittedEvent(COMMITTED_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); |
} else { |
PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", |
timing_.first_layout); |
- RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); |
+ RecordCommittedEvent(COMMITTED_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); |
} |
} |
+ // Log time to first foreground / time to first background. Log counts that we |
+ // started a relevant page load in the foreground / background. |
+ if (!background_time_.is_null()) { |
+ PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstBackground", |
+ background_delta); |
+ } else if (!foreground_time_.is_null()) { |
+ PAGE_LOAD_HISTOGRAM( |
+ "PageLoad.Timing2.NavigationToFirstForeground", |
+ WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start); |
+ } |
+} |
+void PageLoadTracker::RecordProvisionalEvent(ProvisionalLoadEvent event) { |
+ UMA_HISTOGRAM_ENUMERATION("PageLoad.Events.Provisional", event, |
+ PROVISIONAL_LOAD_LAST_ENTRY); |
} |
-void PageLoadTracker::RecordEvent(PageLoadEvent event) { |
- UMA_HISTOGRAM_ENUMERATION( |
- "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); |
+void PageLoadTracker::RecordCommittedEvent(CommittedLoadEvent event) { |
+ UMA_HISTOGRAM_ENUMERATION("PageLoad.Events.Committed", event, |
+ COMMITTED_LOAD_LAST_ENTRY); |
} |
MetricsWebContentsObserver::MetricsWebContentsObserver( |
@@ -197,11 +217,13 @@ void MetricsWebContentsObserver::DidFinishNavigation( |
// Handle a pre-commit error here. Navigations that result in an error page |
// will be ignored. |
if (!navigation_handle->HasCommitted()) { |
- finished_nav->RecordEvent(PAGE_LOAD_FAILED_BEFORE_COMMIT); |
if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED) |
- finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_COMMIT); |
+ finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_ABORTED); |
+ else |
+ finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_FAILED_NON_ABORT); |
return; |
} |
+ finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_COMMITTED); |
// Don't treat a same-page nav as a new page load. |
if (navigation_handle->IsSamePage()) |
@@ -220,6 +242,11 @@ void MetricsWebContentsObserver::DidFinishNavigation( |
void MetricsWebContentsObserver::WasShown() { |
in_foreground_ = true; |
+ if (committed_load_) |
+ committed_load_->WebContentsShown(); |
+ for (const auto& kv : provisional_loads_) { |
+ kv.second->WebContentsShown(); |
+ } |
} |
void MetricsWebContentsObserver::WasHidden() { |