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

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: Some fix ups with the move to //chrome 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 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 270 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
270 DCHECK_NE(static_cast<bool>(info.time_to_commit), 271 DCHECK_NE(static_cast<bool>(info.time_to_commit),
271 static_cast<bool>(failed_provisional_load_info_)); 272 static_cast<bool>(failed_provisional_load_info_));
272 if (info.time_to_commit && timing_.IsEmpty()) { 273 if (info.time_to_commit && timing_.IsEmpty()) {
273 RecordInternalError(ERR_NO_IPCS_RECEIVED); 274 RecordInternalError(ERR_NO_IPCS_RECEIVED);
274 const base::TimeTicks commit_time = 275 const base::TimeTicks commit_time =
275 navigation_start_ + info.time_to_commit.value(); 276 navigation_start_ + info.time_to_commit.value();
276 PAGE_LOAD_HISTOGRAM(internal::kCommitToCompleteNoTimingIPCs, 277 PAGE_LOAD_HISTOGRAM(internal::kCommitToCompleteNoTimingIPCs,
277 base::TimeTicks::Now() - commit_time); 278 base::TimeTicks::Now() - commit_time);
278 } 279 }
279 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their 280
280 // chain length added to the next navigation. Take care not to double count 281 // Don't include any aborts that resulted in a new navigation, as the chain
281 // them. Also do not double count committed loads, which call this already. 282 // length will be included in the aborter PageLoadTracker.
282 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) 283 if (commit_time_.is_null() && abort_type_ != ABORT_RELOAD &&
284 abort_type_ != ABORT_FORWARD_BACK &&
285 abort_type_ != ABORT_NEW_NAVIGATION) {
283 LogAbortChainHistograms(nullptr); 286 LogAbortChainHistograms(nullptr);
287 }
284 288
285 for (const auto& observer : observers_) { 289 for (const auto& observer : observers_) {
286 if (failed_provisional_load_info_) { 290 if (failed_provisional_load_info_) {
287 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info); 291 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info);
288 } else { 292 } else {
289 observer->OnComplete(timing_, info); 293 observer->OnComplete(timing_, info);
290 } 294 }
291 } 295 }
292 } 296 }
293 297
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 for (const auto& observer : observers_) 369 for (const auto& observer : observers_)
366 observer->OnShown(); 370 observer->OnShown();
367 } 371 }
368 372
369 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { 373 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) {
370 // TODO(bmcquade): To improve accuracy, consider adding commit time to 374 // TODO(bmcquade): To improve accuracy, consider adding commit time to
371 // NavigationHandle. Taking a timestamp here should be close enough for now. 375 // NavigationHandle. Taking a timestamp here should be close enough for now.
372 commit_time_ = base::TimeTicks::Now(); 376 commit_time_ = base::TimeTicks::Now();
373 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_); 377 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_);
374 url_ = navigation_handle->GetURL(); 378 url_ = navigation_handle->GetURL();
379 // Some transitions (like CLIENT_REDIRECT) are only known at commit time.
380 page_transition_ = navigation_handle->GetPageTransition();
375 for (const auto& observer : observers_) { 381 for (const auto& observer : observers_) {
376 observer->OnCommit(navigation_handle); 382 observer->OnCommit(navigation_handle);
377 } 383 }
378 LogAbortChainHistograms(navigation_handle); 384 LogAbortChainHistograms(navigation_handle);
379 } 385 }
380 386
381 void PageLoadTracker::FailedProvisionalLoad( 387 void PageLoadTracker::FailedProvisionalLoad(
382 content::NavigationHandle* navigation_handle) { 388 content::NavigationHandle* navigation_handle) {
383 DCHECK(!failed_provisional_load_info_); 389 DCHECK(!failed_provisional_load_info_);
384 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( 390 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); 545 DCHECK_EQ(abort_type_, ABORT_OTHER);
540 546
541 // For some aborts (e.g. navigations), the initiated timestamp can be earlier 547 // 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 548 // than the timestamp that aborted the load. Taking the minimum gives the
543 // closest user initiated time known. 549 // closest user initiated time known.
544 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp), 550 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp),
545 is_certainly_browser_timestamp); 551 is_certainly_browser_timestamp);
546 } 552 }
547 553
548 bool PageLoadTracker::IsLikelyProvisionalAbort( 554 bool PageLoadTracker::IsLikelyProvisionalAbort(
549 base::TimeTicks abort_cause_time) { 555 base::TimeTicks abort_cause_time) const {
550 // Note that |abort_cause_time - abort_time| can be negative. 556 // Note that |abort_cause_time - abort_time| can be negative.
551 return abort_type_ == ABORT_OTHER && 557 return abort_type_ == ABORT_OTHER &&
552 (abort_cause_time - abort_time_).InMilliseconds() < 100; 558 (abort_cause_time - abort_time_).InMilliseconds() < 100;
553 } 559 }
554 560
555 bool PageLoadTracker::MatchesOriginalNavigation( 561 bool PageLoadTracker::MatchesOriginalNavigation(
556 content::NavigationHandle* navigation_handle) { 562 content::NavigationHandle* navigation_handle) {
557 // Neither navigation should have committed. 563 // Neither navigation should have committed.
558 DCHECK(!navigation_handle->HasCommitted()); 564 DCHECK(!navigation_handle->HasCommitted());
559 DCHECK(commit_time_.is_null()); 565 DCHECK(commit_time_.is_null());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 646 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
641 bool handled = true; 647 bool handled = true;
642 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message, 648 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message,
643 render_frame_host) 649 render_frame_host)
644 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) 650 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated)
645 IPC_MESSAGE_UNHANDLED(handled = false) 651 IPC_MESSAGE_UNHANDLED(handled = false)
646 IPC_END_MESSAGE_MAP() 652 IPC_END_MESSAGE_MAP()
647 return handled; 653 return handled;
648 } 654 }
649 655
650 void MetricsWebContentsObserver::DidStartNavigation( 656 void MetricsWebContentsObserver::WillStartNavigationRequest(
651 content::NavigationHandle* navigation_handle) { 657 content::NavigationHandle* navigation_handle) {
652 if (!navigation_handle->IsInMainFrame()) 658 if (!navigation_handle->IsInMainFrame())
653 return; 659 return;
654 660
655 std::unique_ptr<PageLoadTracker> last_aborted = 661 std::unique_ptr<PageLoadTracker> last_aborted =
656 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle); 662 NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle);
657 663
658 int chain_size_same_url = 0; 664 int chain_size_same_url = 0;
659 int chain_size = 0; 665 int chain_size = 0;
660 if (last_aborted) { 666 if (last_aborted) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 } 865 }
860 866
861 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { 867 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) {
862 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true); 868 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true);
863 } 869 }
864 870
865 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( 871 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
866 UserAbortType abort_type, 872 UserAbortType abort_type,
867 base::TimeTicks timestamp, 873 base::TimeTicks timestamp,
868 bool is_certainly_browser_timestamp) { 874 bool is_certainly_browser_timestamp) {
869 if (committed_load_) 875 if (committed_load_) {
870 committed_load_->NotifyAbort(abort_type, timestamp, 876 committed_load_->NotifyAbort(abort_type, timestamp,
871 is_certainly_browser_timestamp); 877 is_certainly_browser_timestamp);
878 }
872 for (const auto& kv : provisional_loads_) { 879 for (const auto& kv : provisional_loads_) {
873 kv.second->NotifyAbort(abort_type, timestamp, 880 kv.second->NotifyAbort(abort_type, timestamp,
874 is_certainly_browser_timestamp); 881 is_certainly_browser_timestamp);
875 } 882 }
876 for (const auto& tracker : aborted_provisional_loads_) { 883 for (const auto& tracker : aborted_provisional_loads_) {
877 if (tracker->IsLikelyProvisionalAbort(timestamp)) 884 if (tracker->IsLikelyProvisionalAbort(timestamp)) {
878 tracker->UpdateAbort(abort_type, timestamp, 885 tracker->UpdateAbort(abort_type, timestamp,
879 is_certainly_browser_timestamp); 886 is_certainly_browser_timestamp);
887 }
880 } 888 }
881 aborted_provisional_loads_.clear(); 889 aborted_provisional_loads_.clear();
882 } 890 }
883 891
884 std::unique_ptr<PageLoadTracker> 892 std::unique_ptr<PageLoadTracker>
885 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( 893 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
886 content::NavigationHandle* new_navigation) { 894 content::NavigationHandle* new_navigation) {
887 // If there are multiple aborted loads that can be attributed to this one, 895 // 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 896 // just count the latest one for simplicity. Other loads will fall into the
889 // OTHER bucket, though there shouldn't be very many. 897 // OTHER bucket, though there shouldn't be very many.
890 if (aborted_provisional_loads_.size() == 0) 898 if (aborted_provisional_loads_.size() == 0)
891 return nullptr; 899 return nullptr;
892 if (aborted_provisional_loads_.size() > 1) 900 if (aborted_provisional_loads_.size() > 1)
893 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); 901 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS);
894 902
895 std::unique_ptr<PageLoadTracker> last_aborted_load = 903 std::unique_ptr<PageLoadTracker> last_aborted_load =
896 std::move(aborted_provisional_loads_.back()); 904 std::move(aborted_provisional_loads_.back());
897 aborted_provisional_loads_.pop_back(); 905 aborted_provisional_loads_.pop_back();
898 906
899 base::TimeTicks timestamp = new_navigation->NavigationStart(); 907 base::TimeTicks timestamp = new_navigation->NavigationStart();
900 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) 908 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) {
901 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false); 909 last_aborted_load->UpdateAbort(
910 AbortTypeForPageTransition(new_navigation->GetPageTransition()),
911 timestamp, false);
912 }
902 913
903 aborted_provisional_loads_.clear(); 914 aborted_provisional_loads_.clear();
904 return last_aborted_load; 915 return last_aborted_load;
905 } 916 }
906 917
907 void MetricsWebContentsObserver::OnTimingUpdated( 918 void MetricsWebContentsObserver::OnTimingUpdated(
908 content::RenderFrameHost* render_frame_host, 919 content::RenderFrameHost* render_frame_host,
909 const PageLoadTiming& timing, 920 const PageLoadTiming& timing,
910 const PageLoadMetadata& metadata) { 921 const PageLoadMetadata& metadata) {
911 bool error = false; 922 bool error = false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage()) 962 if (navigation_handle->IsSamePage() || navigation_handle->IsErrorPage())
952 return false; 963 return false;
953 const std::string& mime_type = web_contents()->GetContentsMimeType(); 964 const std::string& mime_type = web_contents()->GetContentsMimeType();
954 if (mime_type != "text/html" && mime_type != "application/xhtml+xml") 965 if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
955 return false; 966 return false;
956 } 967 }
957 return true; 968 return true;
958 } 969 }
959 970
960 } // namespace page_load_metrics 971 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698