 Chromium Code Reviews
 Chromium Code Reviews Issue 2481013007:
  Improve tracking of user initiated page loads.  (Closed)
    
  
    Issue 2481013007:
  Improve tracking of user initiated page loads.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/page_load_metrics/page_load_tracker.h" | 5 #include "chrome/browser/page_load_metrics/page_load_tracker.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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 } | 80 } | 
| 81 | 81 | 
| 82 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url) { | 82 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url) { | 
| 83 if (aborted_chain_size_same_url > 0) { | 83 if (aborted_chain_size_same_url > 0) { | 
| 84 UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL, | 84 UMA_HISTOGRAM_COUNTS(internal::kAbortChainSizeSameURL, | 
| 85 aborted_chain_size_same_url); | 85 aborted_chain_size_same_url); | 
| 86 } | 86 } | 
| 87 } | 87 } | 
| 88 | 88 | 
| 89 // TODO(crbug.com/617904): Browser initiated navigations should have | 89 // TODO(crbug.com/617904): Browser initiated navigations should have | 
| 90 // HasUserGesture() set to true. Update this once we get enough data from just | 90 // HasUserGesture() set to true. In the meantime, we consider all | 
| 91 // renderer initiated aborts. | 91 // browser-initiated navigations to be user initiated. | 
| 92 bool IsNavigationUserInitiated(content::NavigationHandle* handle) { | 92 bool IsNavigationUserInitiated(content::NavigationHandle* handle) { | 
| 93 return handle->HasUserGesture(); | 93 return handle->HasUserGesture() || !handle->IsRendererInitiated(); | 
| 
Charlie Harrison
2016/11/10 22:26:05
Can you reference the crbug that shows this proper
 
Bryan McQuade
2016/11/10 22:52:50
Done
 | |
| 94 } | 94 } | 
| 95 | 95 | 
| 96 namespace { | 96 namespace { | 
| 97 | 97 | 
| 98 // Helper to allow use of Optional<> values in LOG() messages. | 98 // Helper to allow use of Optional<> values in LOG() messages. | 
| 99 std::ostream& operator<<(std::ostream& os, | 99 std::ostream& operator<<(std::ostream& os, | 
| 100 const base::Optional<base::TimeDelta>& opt) { | 100 const base::Optional<base::TimeDelta>& opt) { | 
| 101 if (opt) | 101 if (opt) | 
| 102 os << opt.value(); | 102 os << opt.value(); | 
| 103 else | 103 else | 
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 : did_stop_tracking_(false), | 287 : did_stop_tracking_(false), | 
| 288 app_entered_background_(false), | 288 app_entered_background_(false), | 
| 289 navigation_start_(navigation_handle->NavigationStart()), | 289 navigation_start_(navigation_handle->NavigationStart()), | 
| 290 start_url_(navigation_handle->GetURL()), | 290 start_url_(navigation_handle->GetURL()), | 
| 291 abort_type_(ABORT_NONE), | 291 abort_type_(ABORT_NONE), | 
| 292 abort_user_initiated_(false), | 292 abort_user_initiated_(false), | 
| 293 started_in_foreground_(in_foreground), | 293 started_in_foreground_(in_foreground), | 
| 294 page_transition_(navigation_handle->GetPageTransition()), | 294 page_transition_(navigation_handle->GetPageTransition()), | 
| 295 num_cache_requests_(0), | 295 num_cache_requests_(0), | 
| 296 num_network_requests_(0), | 296 num_network_requests_(0), | 
| 297 user_gesture_(IsNavigationUserInitiated(navigation_handle)), | 297 user_initiated_(IsNavigationUserInitiated(navigation_handle)), | 
| 298 aborted_chain_size_(aborted_chain_size), | 298 aborted_chain_size_(aborted_chain_size), | 
| 299 aborted_chain_size_same_url_(aborted_chain_size_same_url), | 299 aborted_chain_size_same_url_(aborted_chain_size_same_url), | 
| 300 embedder_interface_(embedder_interface) { | 300 embedder_interface_(embedder_interface) { | 
| 301 DCHECK(!navigation_handle->HasCommitted()); | 301 DCHECK(!navigation_handle->HasCommitted()); | 
| 302 if (embedder_interface_->IsPrerendering( | 302 if (embedder_interface_->IsPrerendering( | 
| 303 navigation_handle->GetWebContents())) { | 303 navigation_handle->GetWebContents())) { | 
| 304 DCHECK(!started_in_foreground_); | 304 DCHECK(!started_in_foreground_); | 
| 305 // For the time being, we do not track prerenders. See crbug.com/648338 for | 305 // For the time being, we do not track prerenders. See crbug.com/648338 for | 
| 306 // details. | 306 // details. | 
| 307 StopTracking(); | 307 StopTracking(); | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 ClampBrowserTimestampIfInterProcessTimeTickSkew(&foreground_time_); | 428 ClampBrowserTimestampIfInterProcessTimeTickSkew(&foreground_time_); | 
| 429 } | 429 } | 
| 430 | 430 | 
| 431 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnShown); | 431 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnShown); | 
| 432 } | 432 } | 
| 433 | 433 | 
| 434 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { | 434 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { | 
| 435 committed_url_ = navigation_handle->GetURL(); | 435 committed_url_ = navigation_handle->GetURL(); | 
| 436 // Some transitions (like CLIENT_REDIRECT) are only known at commit time. | 436 // Some transitions (like CLIENT_REDIRECT) are only known at commit time. | 
| 437 page_transition_ = navigation_handle->GetPageTransition(); | 437 page_transition_ = navigation_handle->GetPageTransition(); | 
| 438 user_gesture_ = navigation_handle->HasUserGesture(); | 438 user_initiated_ = IsNavigationUserInitiated(navigation_handle); | 
| 439 | 439 | 
| 440 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); | 440 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); | 
| 441 LogAbortChainHistograms(navigation_handle); | 441 LogAbortChainHistograms(navigation_handle); | 
| 442 } | 442 } | 
| 443 | 443 | 
| 444 void PageLoadTracker::FailedProvisionalLoad( | 444 void PageLoadTracker::FailedProvisionalLoad( | 
| 445 content::NavigationHandle* navigation_handle) { | 445 content::NavigationHandle* navigation_handle) { | 
| 446 DCHECK(!failed_provisional_load_info_); | 446 DCHECK(!failed_provisional_load_info_); | 
| 447 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( | 447 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( | 
| 448 base::TimeTicks::Now() - navigation_handle->NavigationStart(), | 448 base::TimeTicks::Now() - navigation_handle->NavigationStart(), | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 DCHECK_GE(abort_time_, navigation_start_); | 587 DCHECK_GE(abort_time_, navigation_start_); | 
| 588 time_to_abort = abort_time_ - navigation_start_; | 588 time_to_abort = abort_time_ - navigation_start_; | 
| 589 } else { | 589 } else { | 
| 590 DCHECK(abort_time_.is_null()); | 590 DCHECK(abort_time_.is_null()); | 
| 591 } | 591 } | 
| 592 | 592 | 
| 593 // abort_type_ == ABORT_NONE implies !abort_user_initiated_. | 593 // abort_type_ == ABORT_NONE implies !abort_user_initiated_. | 
| 594 DCHECK(abort_type_ != ABORT_NONE || !abort_user_initiated_); | 594 DCHECK(abort_type_ != ABORT_NONE || !abort_user_initiated_); | 
| 595 return PageLoadExtraInfo( | 595 return PageLoadExtraInfo( | 
| 596 first_background_time, first_foreground_time, started_in_foreground_, | 596 first_background_time, first_foreground_time, started_in_foreground_, | 
| 597 user_gesture_, committed_url_, start_url_, abort_type_, | 597 user_initiated_, committed_url_, start_url_, abort_type_, | 
| 598 abort_user_initiated_, time_to_abort, num_cache_requests_, | 598 abort_user_initiated_, time_to_abort, num_cache_requests_, | 
| 599 num_network_requests_, metadata_); | 599 num_network_requests_, metadata_); | 
| 600 } | 600 } | 
| 601 | 601 | 
| 602 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, | 602 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, | 
| 603 bool user_initiated, | 603 bool user_initiated, | 
| 604 base::TimeTicks timestamp, | 604 base::TimeTicks timestamp, | 
| 605 bool is_certainly_browser_timestamp) { | 605 bool is_certainly_browser_timestamp) { | 
| 606 DCHECK_NE(abort_type, ABORT_NONE); | 606 DCHECK_NE(abort_type, ABORT_NONE); | 
| 607 // Use UpdateAbort to update an already notified PageLoadTracker. | 607 // Use UpdateAbort to update an already notified PageLoadTracker. | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 // instead report the actual cause of an aborted navigation. See crbug/571647 | 657 // instead report the actual cause of an aborted navigation. See crbug/571647 | 
| 658 // for details. | 658 // for details. | 
| 659 if (timestamp < navigation_start_) { | 659 if (timestamp < navigation_start_) { | 
| 660 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); | 660 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); | 
| 661 abort_type_ = ABORT_NONE; | 661 abort_type_ = ABORT_NONE; | 
| 662 abort_time_ = base::TimeTicks(); | 662 abort_time_ = base::TimeTicks(); | 
| 663 return; | 663 return; | 
| 664 } | 664 } | 
| 665 abort_type_ = abort_type; | 665 abort_type_ = abort_type; | 
| 666 abort_time_ = timestamp; | 666 abort_time_ = timestamp; | 
| 667 // A client redirect can never be user initiated. Due to the way Blink | |
| 668 // implements user gesture tracking, where all events that occur within 1 | |
| 669 // second after a user interaction are considered to be triggered by user | |
| 670 // activation (based on HTML spec: | |
| 671 // https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-a ctivation), | |
| 672 // these navs may sometimes be reported as user initiated by Blink. Thus, we | |
| 673 // explicitly filter these types of aborts out when deciding if the abort was | |
| 674 // user initiated. | |
| 667 abort_user_initiated_ = user_initiated && abort_type != ABORT_CLIENT_REDIRECT; | 675 abort_user_initiated_ = user_initiated && abort_type != ABORT_CLIENT_REDIRECT; | 
| 668 | 676 | 
| 669 if (is_certainly_browser_timestamp) { | 677 if (is_certainly_browser_timestamp) { | 
| 670 ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_); | 678 ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_); | 
| 671 } | 679 } | 
| 672 } | 680 } | 
| 673 | 681 | 
| 674 } // namespace page_load_metrics | 682 } // namespace page_load_metrics | 
| OLD | NEW |