| Index: chrome/browser/page_load_metrics/page_load_tracker.cc
|
| diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc
|
| index 72e073d84967f72b2be39886d165abf028672a2c..f01486e7a0ea07f1f24154b2f5e099122e63ff51 100644
|
| --- a/chrome/browser/page_load_metrics/page_load_tracker.cc
|
| +++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
|
| @@ -64,20 +64,20 @@ void RecordInternalError(InternalErrorLoadEvent event) {
|
|
|
| // TODO(csharrison): Add a case for client side redirects, which is what JS
|
| // initiated window.location / window.history navigations get set to.
|
| -UserAbortType AbortTypeForPageTransition(ui::PageTransition transition) {
|
| +PageEndReason EndReasonForPageTransition(ui::PageTransition transition) {
|
| if (transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) {
|
| - return ABORT_CLIENT_REDIRECT;
|
| + return END_CLIENT_REDIRECT;
|
| }
|
| if (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD))
|
| - return ABORT_RELOAD;
|
| + return END_RELOAD;
|
| if (transition & ui::PAGE_TRANSITION_FORWARD_BACK)
|
| - return ABORT_FORWARD_BACK;
|
| + return END_FORWARD_BACK;
|
| if (ui::PageTransitionIsNewNavigation(transition))
|
| - return ABORT_NEW_NAVIGATION;
|
| + return END_NEW_NAVIGATION;
|
| NOTREACHED()
|
| - << "AbortTypeForPageTransition received unexpected ui::PageTransition: "
|
| + << "EndReasonForPageTransition received unexpected ui::PageTransition: "
|
| << transition;
|
| - return ABORT_OTHER;
|
| + return END_OTHER;
|
| }
|
|
|
| void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url) {
|
| @@ -297,8 +297,8 @@ PageLoadTracker::PageLoadTracker(
|
| url_(navigation_handle->GetURL()),
|
| start_url_(navigation_handle->GetURL()),
|
| did_commit_(false),
|
| - abort_type_(ABORT_NONE),
|
| - abort_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()),
|
| + page_end_reason_(END_NONE),
|
| + page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()),
|
| started_in_foreground_(in_foreground),
|
| page_transition_(navigation_handle->GetPageTransition()),
|
| user_initiated_info_(user_initiated_info),
|
| @@ -319,14 +319,20 @@ PageLoadTracker::~PageLoadTracker() {
|
| if (did_stop_tracking_)
|
| return;
|
|
|
| + if (page_end_time_.is_null()) {
|
| + RecordInternalError(ERR_NO_PAGE_LOAD_END_TIME);
|
| + page_end_time_ = base::TimeTicks::Now();
|
| + }
|
| +
|
| if (!did_commit_) {
|
| if (!failed_provisional_load_info_)
|
| RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD);
|
|
|
| // Don't include any aborts that resulted in a new navigation, as the chain
|
| // length will be included in the aborter PageLoadTracker.
|
| - if (abort_type_ != ABORT_RELOAD && abort_type_ != ABORT_FORWARD_BACK &&
|
| - abort_type_ != ABORT_NEW_NAVIGATION) {
|
| + if (page_end_reason_ != END_RELOAD &&
|
| + page_end_reason_ != END_FORWARD_BACK &&
|
| + page_end_reason_ != END_NEW_NAVIGATION) {
|
| LogAbortChainHistograms(nullptr);
|
| }
|
| } else if (timing_.IsEmpty()) {
|
| @@ -367,12 +373,12 @@ void PageLoadTracker::LogAbortChainHistograms(
|
|
|
| ui::PageTransition committed_transition =
|
| final_navigation->GetPageTransition();
|
| - switch (AbortTypeForPageTransition(committed_transition)) {
|
| - case ABORT_RELOAD:
|
| + switch (EndReasonForPageTransition(committed_transition)) {
|
| + case END_RELOAD:
|
| UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeReload,
|
| aborted_chain_size_);
|
| return;
|
| - case ABORT_FORWARD_BACK:
|
| + case END_FORWARD_BACK:
|
| UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeForwardBack,
|
| aborted_chain_size_);
|
| return;
|
| @@ -381,8 +387,8 @@ void PageLoadTracker::LogAbortChainHistograms(
|
| // chain, log a histogram of the counts of each of these metrics. For now,
|
| // merge client redirects with new navigations, which was (basically) the
|
| // previous behavior.
|
| - case ABORT_CLIENT_REDIRECT:
|
| - case ABORT_NEW_NAVIGATION:
|
| + case END_CLIENT_REDIRECT:
|
| + case END_NEW_NAVIGATION:
|
| UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeNewNavigation,
|
| aborted_chain_size_);
|
| return;
|
| @@ -403,12 +409,6 @@ void PageLoadTracker::WebContentsHidden() {
|
| DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
|
| background_time_ = base::TimeTicks::Now();
|
| ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
|
| - // Though most cases where a tab is backgrounded are user initiated, we
|
| - // can't be certain that we were backgrounded due to a user action. For
|
| - // example, on Android, the screen times out after a period of inactivity,
|
| - // resulting in a non-user-initiated backgrounding.
|
| - NotifyAbort(ABORT_BACKGROUND, UserInitiatedInfo::NotUserInitiated(),
|
| - background_time_, true);
|
| }
|
| const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
|
| INVOKE_AND_PRUNE_OBSERVERS(observers_, OnHidden, timing_, info);
|
| @@ -454,10 +454,11 @@ void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) {
|
| }
|
|
|
| void PageLoadTracker::FailedProvisionalLoad(
|
| - content::NavigationHandle* navigation_handle) {
|
| + content::NavigationHandle* navigation_handle,
|
| + base::TimeTicks failed_load_time) {
|
| DCHECK(!failed_provisional_load_info_);
|
| failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo(
|
| - base::TimeTicks::Now() - navigation_handle->NavigationStart(),
|
| + failed_load_time - navigation_handle->NavigationStart(),
|
| navigation_handle->GetNetErrorCode()));
|
| }
|
|
|
| @@ -584,7 +585,7 @@ void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew(
|
| PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() {
|
| base::Optional<base::TimeDelta> first_background_time;
|
| base::Optional<base::TimeDelta> first_foreground_time;
|
| - base::Optional<base::TimeDelta> time_to_abort;
|
| + base::Optional<base::TimeDelta> page_end_time;
|
|
|
| if (!background_time_.is_null()) {
|
| DCHECK_GE(background_time_, navigation_start_);
|
| @@ -596,23 +597,23 @@ PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() {
|
| first_foreground_time = foreground_time_ - navigation_start_;
|
| }
|
|
|
| - if (abort_type_ != ABORT_NONE) {
|
| - DCHECK_GE(abort_time_, navigation_start_);
|
| - time_to_abort = abort_time_ - navigation_start_;
|
| + if (page_end_reason_ != END_NONE) {
|
| + DCHECK_GE(page_end_time_, navigation_start_);
|
| + page_end_time = page_end_time_ - navigation_start_;
|
| } else {
|
| - DCHECK(abort_time_.is_null());
|
| + DCHECK(page_end_time_.is_null());
|
| }
|
|
|
| - // abort_type_ == ABORT_NONE implies abort_user_initiated_info_ is not user
|
| - // initiated.
|
| - DCHECK(abort_type_ != ABORT_NONE ||
|
| - (!abort_user_initiated_info_.browser_initiated &&
|
| - !abort_user_initiated_info_.user_gesture &&
|
| - !abort_user_initiated_info_.user_input_event));
|
| + // page_end_reason_ == END_NONE implies page_end_user_initiated_info_ is not
|
| + // user initiated.
|
| + DCHECK(page_end_reason_ != END_NONE ||
|
| + (!page_end_user_initiated_info_.browser_initiated &&
|
| + !page_end_user_initiated_info_.user_gesture &&
|
| + !page_end_user_initiated_info_.user_input_event));
|
| return PageLoadExtraInfo(
|
| first_background_time, first_foreground_time, started_in_foreground_,
|
| - user_initiated_info_, url(), start_url_, did_commit_, abort_type_,
|
| - abort_user_initiated_info_, time_to_abort, metadata_);
|
| + user_initiated_info_, url(), start_url_, did_commit_, page_end_reason_,
|
| + page_end_user_initiated_info_, page_end_time, metadata_);
|
| }
|
|
|
| bool PageLoadTracker::HasMatchingNavigationRequestID(
|
| @@ -622,40 +623,43 @@ bool PageLoadTracker::HasMatchingNavigationRequestID(
|
| navigation_request_id_.value() == request_id;
|
| }
|
|
|
| -void PageLoadTracker::NotifyAbort(UserAbortType abort_type,
|
| - UserInitiatedInfo user_initiated_info,
|
| - base::TimeTicks timestamp,
|
| - bool is_certainly_browser_timestamp) {
|
| - DCHECK_NE(abort_type, ABORT_NONE);
|
| - // Use UpdateAbort to update an already notified PageLoadTracker.
|
| - if (abort_type_ != ABORT_NONE)
|
| +void PageLoadTracker::NotifyPageEnd(PageEndReason page_end_reason,
|
| + UserInitiatedInfo user_initiated_info,
|
| + base::TimeTicks timestamp,
|
| + bool is_certainly_browser_timestamp) {
|
| + DCHECK_NE(page_end_reason, END_NONE);
|
| + // Use UpdatePageEnd to update an already notified PageLoadTracker.
|
| + if (page_end_reason_ != END_NONE)
|
| return;
|
|
|
| - UpdateAbortInternal(abort_type, user_initiated_info, timestamp,
|
| - is_certainly_browser_timestamp);
|
| + UpdatePageEndInternal(page_end_reason, user_initiated_info, timestamp,
|
| + is_certainly_browser_timestamp);
|
| }
|
|
|
| -void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
|
| - UserInitiatedInfo user_initiated_info,
|
| - base::TimeTicks timestamp,
|
| - bool is_certainly_browser_timestamp) {
|
| - DCHECK_NE(abort_type, ABORT_NONE);
|
| - DCHECK_NE(abort_type, ABORT_OTHER);
|
| - DCHECK_EQ(abort_type_, ABORT_OTHER);
|
| +void PageLoadTracker::UpdatePageEnd(PageEndReason page_end_reason,
|
| + UserInitiatedInfo user_initiated_info,
|
| + base::TimeTicks timestamp,
|
| + bool is_certainly_browser_timestamp) {
|
| + DCHECK_NE(page_end_reason, END_NONE);
|
| + DCHECK_NE(page_end_reason, END_OTHER);
|
| + DCHECK_EQ(page_end_reason_, END_OTHER);
|
| + DCHECK(!page_end_time_.is_null());
|
| + if (page_end_time_.is_null() || page_end_reason_ != END_OTHER)
|
| + return;
|
|
|
| // For some aborts (e.g. navigations), the initiated timestamp can be earlier
|
| // than the timestamp that aborted the load. Taking the minimum gives the
|
| // closest user initiated time known.
|
| - UpdateAbortInternal(abort_type, user_initiated_info,
|
| - std::min(abort_time_, timestamp),
|
| - is_certainly_browser_timestamp);
|
| + UpdatePageEndInternal(page_end_reason, user_initiated_info,
|
| + std::min(page_end_time_, timestamp),
|
| + is_certainly_browser_timestamp);
|
| }
|
|
|
| bool PageLoadTracker::IsLikelyProvisionalAbort(
|
| base::TimeTicks abort_cause_time) const {
|
| - // Note that |abort_cause_time - abort_time| can be negative.
|
| - return abort_type_ == ABORT_OTHER &&
|
| - (abort_cause_time - abort_time_).InMilliseconds() < 100;
|
| + // Note that |abort_cause_time - page_end_time_| can be negative.
|
| + return page_end_reason_ == END_OTHER &&
|
| + (abort_cause_time - page_end_time_).InMilliseconds() < 100;
|
| }
|
|
|
| bool PageLoadTracker::MatchesOriginalNavigation(
|
| @@ -666,10 +670,11 @@ bool PageLoadTracker::MatchesOriginalNavigation(
|
| return navigation_handle->GetURL() == start_url_;
|
| }
|
|
|
| -void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
|
| - UserInitiatedInfo user_initiated_info,
|
| - base::TimeTicks timestamp,
|
| - bool is_certainly_browser_timestamp) {
|
| +void PageLoadTracker::UpdatePageEndInternal(
|
| + PageEndReason page_end_reason,
|
| + UserInitiatedInfo user_initiated_info,
|
| + base::TimeTicks timestamp,
|
| + bool is_certainly_browser_timestamp) {
|
| // When a provisional navigation commits, that navigation's start time is
|
| // interpreted as the abort time for other provisional loads in the tab.
|
| // However, this only makes sense if the committed load started after the
|
| @@ -680,13 +685,13 @@ void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
|
| // instead report the actual cause of an aborted navigation. See crbug/571647
|
| // for details.
|
| if (timestamp < navigation_start_) {
|
| - RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START);
|
| - abort_type_ = ABORT_NONE;
|
| - abort_time_ = base::TimeTicks();
|
| + RecordInternalError(ERR_END_BEFORE_NAVIGATION_START);
|
| + page_end_reason_ = END_NONE;
|
| + page_end_time_ = base::TimeTicks();
|
| return;
|
| }
|
| - abort_type_ = abort_type;
|
| - abort_time_ = timestamp;
|
| + page_end_reason_ = page_end_reason;
|
| + page_end_time_ = timestamp;
|
| // A client redirect can never be user initiated. Due to the way Blink
|
| // implements user gesture tracking, where all events that occur within 1
|
| // second after a user interaction are considered to be triggered by user
|
| @@ -695,11 +700,11 @@ void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
|
| // these navs may sometimes be reported as user initiated by Blink. Thus, we
|
| // explicitly filter these types of aborts out when deciding if the abort was
|
| // user initiated.
|
| - if (abort_type != ABORT_CLIENT_REDIRECT)
|
| - abort_user_initiated_info_ = user_initiated_info;
|
| + if (page_end_reason != END_CLIENT_REDIRECT)
|
| + page_end_user_initiated_info_ = user_initiated_info;
|
|
|
| if (is_certainly_browser_timestamp) {
|
| - ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_);
|
| + ClampBrowserTimestampIfInterProcessTimeTickSkew(&page_end_time_);
|
| }
|
| }
|
|
|
|
|