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

Side by Side Diff: chrome/browser/page_load_metrics/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: rebase on #408334 Created 4 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/metrics_web_contents_observer.h" 5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 PageLoadMetricsEmbedderInterface* embedder_interface, 244 PageLoadMetricsEmbedderInterface* embedder_interface,
245 const GURL& currently_committed_url, 245 const GURL& currently_committed_url,
246 content::NavigationHandle* navigation_handle, 246 content::NavigationHandle* navigation_handle,
247 int aborted_chain_size, 247 int aborted_chain_size,
248 int aborted_chain_size_same_url) 248 int aborted_chain_size_same_url)
249 : did_stop_tracking_(false), 249 : did_stop_tracking_(false),
250 navigation_start_(navigation_handle->NavigationStart()), 250 navigation_start_(navigation_handle->NavigationStart()),
251 url_(navigation_handle->GetURL()), 251 url_(navigation_handle->GetURL()),
252 abort_type_(ABORT_NONE), 252 abort_type_(ABORT_NONE),
253 started_in_foreground_(in_foreground), 253 started_in_foreground_(in_foreground),
254 page_transition_(navigation_handle->GetPageTransition()),
254 aborted_chain_size_(aborted_chain_size), 255 aborted_chain_size_(aborted_chain_size),
255 aborted_chain_size_same_url_(aborted_chain_size_same_url), 256 aborted_chain_size_same_url_(aborted_chain_size_same_url),
256 embedder_interface_(embedder_interface) { 257 embedder_interface_(embedder_interface) {
257 DCHECK(!navigation_handle->HasCommitted()); 258 DCHECK(!navigation_handle->HasCommitted());
258 embedder_interface_->RegisterObservers(this); 259 embedder_interface_->RegisterObservers(this);
259 for (const auto& observer : observers_) { 260 for (const auto& observer : observers_) {
260 observer->OnStart(navigation_handle, currently_committed_url, 261 observer->OnStart(navigation_handle, currently_committed_url,
261 started_in_foreground_); 262 started_in_foreground_);
262 } 263 }
263 } 264 }
264 265
265 PageLoadTracker::~PageLoadTracker() { 266 PageLoadTracker::~PageLoadTracker() {
266 if (did_stop_tracking_) 267 if (did_stop_tracking_)
267 return; 268 return;
268 269
269 if (commit_time_.is_null()) { 270 if (commit_time_.is_null()) {
270 if (!failed_provisional_load_info_) 271 if (!failed_provisional_load_info_)
271 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD); 272 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD);
272 273
273 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their 274 // Don't include any aborts that resulted in a new navigation, as the chain
274 // chain length added to the next navigation. Take care not to double count 275 // length will be included in the aborter PageLoadTracker.
275 // them. Also do not double count committed loads, which call this already. 276 if (abort_type_ != ABORT_RELOAD && abort_type_ != ABORT_FORWARD_BACK &&
276 if (abort_type_ != ABORT_UNKNOWN_NAVIGATION) 277 abort_type_ != ABORT_NEW_NAVIGATION) {
277 LogAbortChainHistograms(nullptr); 278 LogAbortChainHistograms(nullptr);
279 }
278 } else if (timing_.IsEmpty()) { 280 } else if (timing_.IsEmpty()) {
279 RecordInternalError(ERR_NO_IPCS_RECEIVED); 281 RecordInternalError(ERR_NO_IPCS_RECEIVED);
280 PAGE_LOAD_HISTOGRAM(internal::kCommitToCompleteNoTimingIPCs, 282 PAGE_LOAD_HISTOGRAM(internal::kCommitToCompleteNoTimingIPCs,
281 base::TimeTicks::Now() - commit_time_); 283 base::TimeTicks::Now() - commit_time_);
282 } 284 }
283 285
284 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 286 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
285 for (const auto& observer : observers_) { 287 for (const auto& observer : observers_) {
286 if (failed_provisional_load_info_) { 288 if (failed_provisional_load_info_) {
287 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info); 289 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 for (const auto& observer : observers_) 367 for (const auto& observer : observers_)
366 observer->OnShown(); 368 observer->OnShown();
367 } 369 }
368 370
369 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { 371 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) {
370 // TODO(bmcquade): To improve accuracy, consider adding commit time to 372 // TODO(bmcquade): To improve accuracy, consider adding commit time to
371 // NavigationHandle. Taking a timestamp here should be close enough for now. 373 // NavigationHandle. Taking a timestamp here should be close enough for now.
372 commit_time_ = base::TimeTicks::Now(); 374 commit_time_ = base::TimeTicks::Now();
373 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_); 375 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_);
374 url_ = navigation_handle->GetURL(); 376 url_ = navigation_handle->GetURL();
377 // Some transitions (like CLIENT_REDIRECT) are only known at commit time.
378 page_transition_ = navigation_handle->GetPageTransition();
375 for (const auto& observer : observers_) { 379 for (const auto& observer : observers_) {
376 observer->OnCommit(navigation_handle); 380 observer->OnCommit(navigation_handle);
377 } 381 }
378 LogAbortChainHistograms(navigation_handle); 382 LogAbortChainHistograms(navigation_handle);
379 } 383 }
380 384
381 void PageLoadTracker::FailedProvisionalLoad( 385 void PageLoadTracker::FailedProvisionalLoad(
382 content::NavigationHandle* navigation_handle) { 386 content::NavigationHandle* navigation_handle) {
383 DCHECK(!failed_provisional_load_info_); 387 DCHECK(!failed_provisional_load_info_);
384 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( 388 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo(
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 DCHECK_EQ(abort_type_, ABORT_OTHER); 543 DCHECK_EQ(abort_type_, ABORT_OTHER);
540 544
541 // For some aborts (e.g. navigations), the initiated timestamp can be earlier 545 // For some aborts (e.g. navigations), the initiated timestamp can be earlier
542 // than the timestamp that aborted the load. Taking the minimum gives the 546 // than the timestamp that aborted the load. Taking the minimum gives the
543 // closest user initiated time known. 547 // closest user initiated time known.
544 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp), 548 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp),
545 is_certainly_browser_timestamp); 549 is_certainly_browser_timestamp);
546 } 550 }
547 551
548 bool PageLoadTracker::IsLikelyProvisionalAbort( 552 bool PageLoadTracker::IsLikelyProvisionalAbort(
549 base::TimeTicks abort_cause_time) { 553 base::TimeTicks abort_cause_time) const {
550 // Note that |abort_cause_time - abort_time| can be negative. 554 // Note that |abort_cause_time - abort_time| can be negative.
551 return abort_type_ == ABORT_OTHER && 555 return abort_type_ == ABORT_OTHER &&
552 (abort_cause_time - abort_time_).InMilliseconds() < 100; 556 (abort_cause_time - abort_time_).InMilliseconds() < 100;
553 } 557 }
554 558
555 bool PageLoadTracker::MatchesOriginalNavigation( 559 bool PageLoadTracker::MatchesOriginalNavigation(
556 content::NavigationHandle* navigation_handle) { 560 content::NavigationHandle* navigation_handle) {
557 // Neither navigation should have committed. 561 // Neither navigation should have committed.
558 DCHECK(!navigation_handle->HasCommitted()); 562 DCHECK(!navigation_handle->HasCommitted());
559 DCHECK(commit_time_.is_null()); 563 DCHECK(commit_time_.is_null());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 644 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
641 bool handled = true; 645 bool handled = true;
642 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message, 646 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message,
643 render_frame_host) 647 render_frame_host)
644 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) 648 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated)
645 IPC_MESSAGE_UNHANDLED(handled = false) 649 IPC_MESSAGE_UNHANDLED(handled = false)
646 IPC_END_MESSAGE_MAP() 650 IPC_END_MESSAGE_MAP()
647 return handled; 651 return handled;
648 } 652 }
649 653
650 void MetricsWebContentsObserver::DidStartNavigation( 654 void MetricsWebContentsObserver::WillStartNavigationRequest(
651 content::NavigationHandle* navigation_handle) { 655 content::NavigationHandle* navigation_handle) {
652 if (!navigation_handle->IsInMainFrame()) 656 if (!navigation_handle->IsInMainFrame())
653 return; 657 return;
654 658
655 std::unique_ptr<PageLoadTracker> last_aborted = 659 std::unique_ptr<PageLoadTracker> last_aborted =
656 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle); 660 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle);
657 661
658 int chain_size_same_url = 0; 662 int chain_size_same_url = 0;
659 int chain_size = 0; 663 int chain_size = 0;
660 if (last_aborted) { 664 if (last_aborted) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 } 863 }
860 864
861 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { 865 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) {
862 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true); 866 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true);
863 } 867 }
864 868
865 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( 869 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
866 UserAbortType abort_type, 870 UserAbortType abort_type,
867 base::TimeTicks timestamp, 871 base::TimeTicks timestamp,
868 bool is_certainly_browser_timestamp) { 872 bool is_certainly_browser_timestamp) {
869 if (committed_load_) 873 if (committed_load_) {
870 committed_load_->NotifyAbort(abort_type, timestamp, 874 committed_load_->NotifyAbort(abort_type, timestamp,
871 is_certainly_browser_timestamp); 875 is_certainly_browser_timestamp);
876 }
872 for (const auto& kv : provisional_loads_) { 877 for (const auto& kv : provisional_loads_) {
873 kv.second->NotifyAbort(abort_type, timestamp, 878 kv.second->NotifyAbort(abort_type, timestamp,
874 is_certainly_browser_timestamp); 879 is_certainly_browser_timestamp);
875 } 880 }
876 for (const auto& tracker : aborted_provisional_loads_) { 881 for (const auto& tracker : aborted_provisional_loads_) {
877 if (tracker->IsLikelyProvisionalAbort(timestamp)) 882 if (tracker->IsLikelyProvisionalAbort(timestamp)) {
878 tracker->UpdateAbort(abort_type, timestamp, 883 tracker->UpdateAbort(abort_type, timestamp,
879 is_certainly_browser_timestamp); 884 is_certainly_browser_timestamp);
885 }
880 } 886 }
881 aborted_provisional_loads_.clear(); 887 aborted_provisional_loads_.clear();
882 } 888 }
883 889
884 std::unique_ptr<PageLoadTracker> 890 std::unique_ptr<PageLoadTracker>
885 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( 891 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
886 content::NavigationHandle* new_navigation) { 892 content::NavigationHandle* new_navigation) {
887 // If there are multiple aborted loads that can be attributed to this one, 893 // If there are multiple aborted loads that can be attributed to this one,
888 // just count the latest one for simplicity. Other loads will fall into the 894 // just count the latest one for simplicity. Other loads will fall into the
889 // OTHER bucket, though there shouldn't be very many. 895 // OTHER bucket, though there shouldn't be very many.
890 if (aborted_provisional_loads_.size() == 0) 896 if (aborted_provisional_loads_.size() == 0)
891 return nullptr; 897 return nullptr;
892 if (aborted_provisional_loads_.size() > 1) 898 if (aborted_provisional_loads_.size() > 1)
893 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); 899 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS);
894 900
895 std::unique_ptr<PageLoadTracker> last_aborted_load = 901 std::unique_ptr<PageLoadTracker> last_aborted_load =
896 std::move(aborted_provisional_loads_.back()); 902 std::move(aborted_provisional_loads_.back());
897 aborted_provisional_loads_.pop_back(); 903 aborted_provisional_loads_.pop_back();
898 904
899 base::TimeTicks timestamp = new_navigation->NavigationStart(); 905 base::TimeTicks timestamp = new_navigation->NavigationStart();
900 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) 906 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) {
901 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false); 907 last_aborted_load->UpdateAbort(
908 AbortTypeForPageTransition(new_navigation->GetPageTransition()),
909 timestamp, false);
910 }
902 911
903 aborted_provisional_loads_.clear(); 912 aborted_provisional_loads_.clear();
904 return last_aborted_load; 913 return last_aborted_load;
905 } 914 }
906 915
907 void MetricsWebContentsObserver::OnTimingUpdated( 916 void MetricsWebContentsObserver::OnTimingUpdated(
908 content::RenderFrameHost* render_frame_host, 917 content::RenderFrameHost* render_frame_host,
909 const PageLoadTiming& timing, 918 const PageLoadTiming& timing,
910 const PageLoadMetadata& metadata) { 919 const PageLoadMetadata& metadata) {
911 // We may receive notifications from frames that have been navigated away 920 // We may receive notifications from frames that have been navigated away
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage()) 961 if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage())
953 return false; 962 return false;
954 const std::string& mime_type = web_contents()->GetContentsMimeType(); 963 const std::string& mime_type = web_contents()->GetContentsMimeType();
955 if (mime_type != "text/html" && mime_type != "application/xhtml+xml") 964 if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
956 return false; 965 return false;
957 } 966 }
958 return true; 967 return true;
959 } 968 }
960 969
961 } // namespace page_load_metrics 970 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698