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

Side by Side Diff: components/page_load_metrics/browser/metrics_web_contents_observer.cc

Issue 1837233002: Optional <TimeDelta> since they may be non existent. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 6 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 "components/page_load_metrics/browser/metrics_web_contents_observer.h" 5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 embedder_interface_(embedder_interface) { 253 embedder_interface_(embedder_interface) {
254 DCHECK(!navigation_handle->HasCommitted()); 254 DCHECK(!navigation_handle->HasCommitted());
255 embedder_interface_->RegisterObservers(this); 255 embedder_interface_->RegisterObservers(this);
256 for (const auto& observer : observers_) { 256 for (const auto& observer : observers_) {
257 observer->OnStart(navigation_handle, currently_committed_url, 257 observer->OnStart(navigation_handle, currently_committed_url,
258 started_in_foreground_); 258 started_in_foreground_);
259 } 259 }
260 } 260 }
261 261
262 PageLoadTracker::~PageLoadTracker() { 262 PageLoadTracker::~PageLoadTracker() {
263 const PageLoadExtraInfo info = GetPageLoadMetricsInfo(); 263 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
264 if (!info.time_to_commit.is_zero() && renderer_tracked() && 264
265 timing_.IsEmpty()) { 265 if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) {
266 RecordInternalError(ERR_NO_IPCS_RECEIVED); 266 RecordInternalError(ERR_NO_IPCS_RECEIVED);
267 } 267 }
268 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their 268 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
269 // chain length added to the next navigation. Take care not to double count 269 // chain length added to the next navigation. Take care not to double count
270 // them. Also do not double count committed loads, which call this already. 270 // them. Also do not double count committed loads, which call this already.
271 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) 271 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION)
272 LogAbortChainHistograms(nullptr); 272 LogAbortChainHistograms(nullptr);
273 273
274 for (const auto& observer : observers_) { 274 for (const auto& observer : observers_) {
275 observer->OnComplete(timing_, info); 275 observer->OnComplete(timing_, info);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 } 322 }
323 323
324 void PageLoadTracker::WebContentsHidden() { 324 void PageLoadTracker::WebContentsHidden() {
325 // Only log the first time we background in a given page load. 325 // Only log the first time we background in a given page load.
326 if (background_time_.is_null()) { 326 if (background_time_.is_null()) {
327 // Make sure we either started in the foreground and haven't been 327 // Make sure we either started in the foreground and haven't been
328 // foregrounded yet, or started in the background and have already been 328 // foregrounded yet, or started in the background and have already been
329 // foregrounded. 329 // foregrounded.
330 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null()); 330 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
331 background_time_ = base::TimeTicks::Now(); 331 background_time_ = base::TimeTicks::Now();
332 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
332 } 333 }
333 334
334 for (const auto& observer : observers_) 335 for (const auto& observer : observers_)
335 observer->OnHidden(); 336 observer->OnHidden();
336 } 337 }
337 338
338 void PageLoadTracker::WebContentsShown() { 339 void PageLoadTracker::WebContentsShown() {
339 // Only log the first time we foreground in a given page load. 340 // Only log the first time we foreground in a given page load.
340 if (foreground_time_.is_null()) { 341 if (foreground_time_.is_null()) {
341 // Make sure we either started in the background and haven't been 342 // Make sure we either started in the background and haven't been
342 // backgrounded yet, or started in the foreground and have already been 343 // backgrounded yet, or started in the foreground and have already been
343 // backgrounded. 344 // backgrounded.
344 DCHECK_NE(started_in_foreground_, background_time_.is_null()); 345 DCHECK_NE(started_in_foreground_, background_time_.is_null());
345 foreground_time_ = base::TimeTicks::Now(); 346 foreground_time_ = base::TimeTicks::Now();
347 ClampBrowserTimestampIfInterProcessTimeTickSkew(&foreground_time_);
346 } 348 }
347 349
348 for (const auto& observer : observers_) 350 for (const auto& observer : observers_)
349 observer->OnShown(); 351 observer->OnShown();
350 } 352 }
351 353
352 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { 354 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) {
353 // TODO(bmcquade): To improve accuracy, consider adding commit time to 355 // TODO(bmcquade): To improve accuracy, consider adding commit time to
354 // NavigationHandle. Taking a timestamp here should be close enough for now. 356 // NavigationHandle. Taking a timestamp here should be close enough for now.
355 commit_time_ = base::TimeTicks::Now(); 357 commit_time_ = base::TimeTicks::Now();
358 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_);
356 url_ = navigation_handle->GetURL(); 359 url_ = navigation_handle->GetURL();
357 for (const auto& observer : observers_) { 360 for (const auto& observer : observers_) {
358 observer->OnCommit(navigation_handle); 361 observer->OnCommit(navigation_handle);
359 } 362 }
360 LogAbortChainHistograms(navigation_handle); 363 LogAbortChainHistograms(navigation_handle);
361 } 364 }
362 365
363 void PageLoadTracker::FailedProvisionalLoad( 366 void PageLoadTracker::FailedProvisionalLoad(
364 content::NavigationHandle* navigation_handle) { 367 content::NavigationHandle* navigation_handle) {
365 for (const auto& observer : observers_) { 368 for (const auto& observer : observers_) {
(...skipping 30 matching lines...) Expand all
396 valid_behavior_descendent) { 399 valid_behavior_descendent) {
397 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() 400 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo()
398 // must be called before DispatchObserverTimingCallbacks, but its 401 // must be called before DispatchObserverTimingCallbacks, but its
399 // implementation depends on the state of metadata_, so we need to update 402 // implementation depends on the state of metadata_, so we need to update
400 // metadata_ before calling GetPageLoadMetricsInfo. Thus, we make a copy of 403 // metadata_ before calling GetPageLoadMetricsInfo. Thus, we make a copy of
401 // timing here, update timing_ and metadata_, and then proceed to dispatch 404 // timing here, update timing_ and metadata_, and then proceed to dispatch
402 // the observer timing callbacks. 405 // the observer timing callbacks.
403 const PageLoadTiming last_timing = timing_; 406 const PageLoadTiming last_timing = timing_;
404 timing_ = new_timing; 407 timing_ = new_timing;
405 metadata_ = new_metadata; 408 metadata_ = new_metadata;
406 const PageLoadExtraInfo info = GetPageLoadMetricsInfo(); 409 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
407 for (const auto& observer : observers_) { 410 for (const auto& observer : observers_) {
408 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, 411 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing,
409 info); 412 info);
410 } 413 }
411 return true; 414 return true;
412 } 415 }
413 return false; 416 return false;
414 } 417 }
415 418
416 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) { 419 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) {
417 renderer_tracked_ = renderer_tracked; 420 renderer_tracked_ = renderer_tracked;
418 } 421 }
419 422
420 void PageLoadTracker::AddObserver( 423 void PageLoadTracker::AddObserver(
421 std::unique_ptr<PageLoadMetricsObserver> observer) { 424 std::unique_ptr<PageLoadMetricsObserver> observer) {
422 observers_.push_back(std::move(observer)); 425 observers_.push_back(std::move(observer));
423 } 426 }
424 427
425 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { 428 void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew(
426 base::TimeDelta first_background_time; 429 base::TimeTicks* event_time) {
427 base::TimeDelta first_foreground_time; 430 DCHECK(event_time != nullptr);
428 base::TimeDelta time_to_abort; 431 // Windows 10 GCE bot non-deterministically failed because TimeTicks::Now()
429 base::TimeDelta time_to_commit; 432 // called in the browser process e.g. commit_time was less than
430 if (!background_time_.is_null()) 433 // navigation_start_ that was populated in the renderer process because the
434 // clock was not system-wide monotonic.
435 // Note that navigation_start_ can also be set in the browser process in
436 // some cases and in those cases event_time should never be <
437 // navigation_start_. If it is due to a code error and it gets clamped in this
438 // function, on high resolution systems it should lead to a dcheck failure.
439
440 // TODO (shivanisha) Currently IsHighResolution is the best way to check
441 // if the clock is system-wide monotonic. However IsHighResolution
442 // does a broader check to see if the clock in use is high resolution
443 // which also implies it is system-wide monotonic (on Windows).
444 if (base::TimeTicks::IsHighResolution()) {
445 return;
Bryan McQuade 2016/06/21 00:59:46 could we also add: DCHECK(event_time->is_null() ||
shivanisha 2016/06/21 17:08:51 Good point. done.
446 }
447
448 if (!event_time->is_null() && *event_time < navigation_start_) {
449 RecordInternalError(ERR_INTER_PROCESS_TIME_TICK_SKEW);
450 *event_time = navigation_start_;
451 }
452 }
453
454 PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() {
455 base::Optional<base::TimeDelta> first_background_time;
456 base::Optional<base::TimeDelta> first_foreground_time;
457 base::Optional<base::TimeDelta> time_to_abort;
458 base::Optional<base::TimeDelta> time_to_commit;
459
460 if (!background_time_.is_null()) {
461 DCHECK_GE(background_time_, navigation_start_);
431 first_background_time = background_time_ - navigation_start_; 462 first_background_time = background_time_ - navigation_start_;
432 if (!foreground_time_.is_null()) 463 }
464
465 if (!foreground_time_.is_null()) {
466 DCHECK_GE(foreground_time_, navigation_start_);
433 first_foreground_time = foreground_time_ - navigation_start_; 467 first_foreground_time = foreground_time_ - navigation_start_;
468 }
469
434 if (abort_type_ != ABORT_NONE) { 470 if (abort_type_ != ABORT_NONE) {
435 DCHECK_GT(abort_time_, navigation_start_); 471 DCHECK_GE(abort_time_, navigation_start_);
436 time_to_abort = abort_time_ - navigation_start_; 472 time_to_abort = abort_time_ - navigation_start_;
437 } else { 473 } else {
438 DCHECK(abort_time_.is_null()); 474 DCHECK(abort_time_.is_null());
439 } 475 }
440 476
441 if (!commit_time_.is_null()) { 477 if (!commit_time_.is_null()) {
442 DCHECK_GT(commit_time_, navigation_start_); 478 DCHECK_GE(commit_time_, navigation_start_);
443 time_to_commit = commit_time_ - navigation_start_; 479 time_to_commit = commit_time_ - navigation_start_;
444 } else {
445 DCHECK(commit_time_.is_null());
446 } 480 }
481
447 return PageLoadExtraInfo( 482 return PageLoadExtraInfo(
448 first_background_time, first_foreground_time, started_in_foreground_, 483 first_background_time, first_foreground_time, started_in_foreground_,
449 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_, 484 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_,
450 time_to_abort, metadata_); 485 time_to_abort, metadata_);
451 } 486 }
452 487
453 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, 488 void PageLoadTracker::NotifyAbort(UserAbortType abort_type,
454 base::TimeTicks timestamp) { 489 base::TimeTicks timestamp,
490 bool is_certainly_browser_timestamp) {
455 DCHECK_NE(abort_type, ABORT_NONE); 491 DCHECK_NE(abort_type, ABORT_NONE);
456 // Use UpdateAbort to update an already notified PageLoadTracker. 492 // Use UpdateAbort to update an already notified PageLoadTracker.
457 if (abort_type_ != ABORT_NONE) 493 if (abort_type_ != ABORT_NONE)
458 return; 494 return;
459 495
460 UpdateAbortInternal(abort_type, timestamp); 496 UpdateAbortInternal(abort_type, timestamp, is_certainly_browser_timestamp);
461 } 497 }
462 498
463 void PageLoadTracker::UpdateAbort(UserAbortType abort_type, 499 void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
464 base::TimeTicks timestamp) { 500 base::TimeTicks timestamp,
501 bool is_certainly_browser_timestamp) {
465 DCHECK_NE(abort_type, ABORT_NONE); 502 DCHECK_NE(abort_type, ABORT_NONE);
466 DCHECK_NE(abort_type, ABORT_OTHER); 503 DCHECK_NE(abort_type, ABORT_OTHER);
467 DCHECK_EQ(abort_type_, ABORT_OTHER); 504 DCHECK_EQ(abort_type_, ABORT_OTHER);
468 505
469 // For some aborts (e.g. navigations), the initiated timestamp can be earlier 506 // For some aborts (e.g. navigations), the initiated timestamp can be earlier
470 // than the timestamp that aborted the load. Taking the minimum gives the 507 // than the timestamp that aborted the load. Taking the minimum gives the
471 // closest user initiated time known. 508 // closest user initiated time known.
472 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp)); 509 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp),
510 is_certainly_browser_timestamp);
473 } 511 }
474 512
475 bool PageLoadTracker::IsLikelyProvisionalAbort( 513 bool PageLoadTracker::IsLikelyProvisionalAbort(
476 base::TimeTicks abort_cause_time) { 514 base::TimeTicks abort_cause_time) {
477 // Note that |abort_cause_time - abort_time| can be negative. 515 // Note that |abort_cause_time - abort_time| can be negative.
478 return abort_type_ == ABORT_OTHER && 516 return abort_type_ == ABORT_OTHER &&
479 (abort_cause_time - abort_time_).InMilliseconds() < 100; 517 (abort_cause_time - abort_time_).InMilliseconds() < 100;
480 } 518 }
481 519
482 bool PageLoadTracker::MatchesOriginalNavigation( 520 bool PageLoadTracker::MatchesOriginalNavigation(
483 content::NavigationHandle* navigation_handle) { 521 content::NavigationHandle* navigation_handle) {
484 // Neither navigation should have committed. 522 // Neither navigation should have committed.
485 DCHECK(!navigation_handle->HasCommitted()); 523 DCHECK(!navigation_handle->HasCommitted());
486 DCHECK(commit_time_.is_null()); 524 DCHECK(commit_time_.is_null());
487 return navigation_handle->GetURL() == url_; 525 return navigation_handle->GetURL() == url_;
488 } 526 }
489 527
490 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type, 528 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
491 base::TimeTicks timestamp) { 529 base::TimeTicks timestamp,
530 bool is_certainly_browser_timestamp) {
492 // When a provisional navigation commits, that navigation's start time is 531 // When a provisional navigation commits, that navigation's start time is
493 // interpreted as the abort time for other provisional loads in the tab. 532 // interpreted as the abort time for other provisional loads in the tab.
494 // However, this only makes sense if the committed load started after the 533 // However, this only makes sense if the committed load started after the
495 // aborted provisional loads started. Thus we ignore cases where the committed 534 // aborted provisional loads started. Thus we ignore cases where the committed
496 // load started before the aborted provisional load, as this would result in 535 // load started before the aborted provisional load, as this would result in
497 // recording a negative time-to-abort. The real issue here is that we have to 536 // recording a negative time-to-abort. The real issue here is that we have to
498 // infer the cause of aborts. It would be better if the navigation code could 537 // infer the cause of aborts. It would be better if the navigation code could
499 // instead report the actual cause of an aborted navigation. See crbug/571647 538 // instead report the actual cause of an aborted navigation. See crbug/571647
500 // for details. 539 // for details.
501 if (timestamp <= navigation_start_) { 540 if (timestamp < navigation_start_) {
502 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); 541 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START);
503 abort_type_ = ABORT_NONE; 542 abort_type_ = ABORT_NONE;
504 abort_time_ = base::TimeTicks(); 543 abort_time_ = base::TimeTicks();
505 return; 544 return;
506 } 545 }
507 abort_type_ = abort_type; 546 abort_type_ = abort_type;
508 abort_time_ = timestamp; 547 abort_time_ = timestamp;
548
549 if (is_certainly_browser_timestamp) {
550 ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_);
551 }
509 } 552 }
510 553
511 // static 554 // static
512 MetricsWebContentsObserver::MetricsWebContentsObserver( 555 MetricsWebContentsObserver::MetricsWebContentsObserver(
513 content::WebContents* web_contents, 556 content::WebContents* web_contents,
514 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) 557 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface)
515 : content::WebContentsObserver(web_contents), 558 : content::WebContentsObserver(web_contents),
516 in_foreground_(false), 559 in_foreground_(false),
517 embedder_interface_(std::move(embedder_interface)), 560 embedder_interface_(std::move(embedder_interface)),
518 has_navigated_(false) { 561 has_navigated_(false) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 // the MetricsWebContentsObserver owns them both list and they are torn down 658 // the MetricsWebContentsObserver owns them both list and they are torn down
616 // after the PageLoadTracker. The PageLoadTracker does not hold on to 659 // after the PageLoadTracker. The PageLoadTracker does not hold on to
617 // committed_load_ or navigation_handle beyond the scope of the constructor. 660 // committed_load_ or navigation_handle beyond the scope of the constructor.
618 provisional_loads_.insert(std::make_pair( 661 provisional_loads_.insert(std::make_pair(
619 navigation_handle, 662 navigation_handle,
620 base::WrapUnique(new PageLoadTracker( 663 base::WrapUnique(new PageLoadTracker(
621 in_foreground_, embedder_interface_.get(), currently_committed_url, 664 in_foreground_, embedder_interface_.get(), currently_committed_url,
622 navigation_handle, chain_size, chain_size_same_url)))); 665 navigation_handle, chain_size, chain_size_same_url))));
623 } 666 }
624 667
668 const PageLoadExtraInfo
669 MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() {
670 DCHECK(committed_load_);
671 return committed_load_->ComputePageLoadExtraInfo();
672 }
673
625 void MetricsWebContentsObserver::DidFinishNavigation( 674 void MetricsWebContentsObserver::DidFinishNavigation(
626 content::NavigationHandle* navigation_handle) { 675 content::NavigationHandle* navigation_handle) {
627 if (!navigation_handle->IsInMainFrame()) 676 if (!navigation_handle->IsInMainFrame())
628 return; 677 return;
629 678
630 std::unique_ptr<PageLoadTracker> finished_nav( 679 std::unique_ptr<PageLoadTracker> finished_nav(
631 std::move(provisional_loads_[navigation_handle])); 680 std::move(provisional_loads_[navigation_handle]));
632 provisional_loads_.erase(navigation_handle); 681 provisional_loads_.erase(navigation_handle);
633 682
634 // There's a chance a navigation could have started before we were added to a 683 // There's a chance a navigation could have started before we were added to a
(...skipping 12 matching lines...) Expand all
647 net::Error error = navigation_handle->GetNetErrorCode(); 696 net::Error error = navigation_handle->GetNetErrorCode();
648 697
649 // net::OK: This case occurs when the NavigationHandle finishes and reports 698 // net::OK: This case occurs when the NavigationHandle finishes and reports
650 // !HasCommitted(), but reports no net::Error. This should not occur 699 // !HasCommitted(), but reports no net::Error. This should not occur
651 // pre-PlzNavigate, but afterwards it should represent the navigation 700 // pre-PlzNavigate, but afterwards it should represent the navigation
652 // stopped by the user before it was ready to commit. 701 // stopped by the user before it was ready to commit.
653 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED. 702 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED.
654 // Note that this can come from some non user-initiated errors, such as 703 // Note that this can come from some non user-initiated errors, such as
655 // downloads, or 204 responses. See crbug.com/542369. 704 // downloads, or 204 responses. See crbug.com/542369.
656 if ((error == net::OK) || (error == net::ERR_ABORTED)) { 705 if ((error == net::OK) || (error == net::ERR_ABORTED)) {
657 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now()); 706 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true);
658 aborted_provisional_loads_.push_back(std::move(finished_nav)); 707 aborted_provisional_loads_.push_back(std::move(finished_nav));
659 } 708 }
660 709
661 return; 710 return;
662 } 711 }
663 712
664 // Don't treat a same-page nav as a new page load. 713 // Don't treat a same-page nav as a new page load.
665 if (navigation_handle->IsSamePage()) 714 if (navigation_handle->IsSamePage())
666 return; 715 return;
667 716
668 // Notify other loads that they may have been aborted by this committed load. 717 // Notify other loads that they may have been aborted by this committed load.
669 // Note that by using the committed navigation start as the abort cause, we 718 // Note that by using the committed navigation start as the abort cause, we
670 // lose data on provisional loads that were aborted by other provisional 719 // lose data on provisional loads that were aborted by other provisional
671 // loads. Those will either be listed as ABORT_OTHER or as being aborted by 720 // loads. Those will either be listed as ABORT_OTHER or as being aborted by
672 // this load. 721 // this load.
722 // is_certainly_browser_timestamp is set to false because NavigationStart()
723 // could be set in either the renderer or browser process.
673 NotifyAbortAllLoadsWithTimestamp( 724 NotifyAbortAllLoadsWithTimestamp(
674 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), 725 AbortTypeForPageTransition(navigation_handle->GetPageTransition()),
675 navigation_handle->NavigationStart()); 726 navigation_handle->NavigationStart(), false);
676 727
677 committed_load_ = std::move(finished_nav); 728 committed_load_ = std::move(finished_nav);
678 aborted_provisional_loads_.clear(); 729 aborted_provisional_loads_.clear();
679 730
680 const GURL& browser_url = web_contents()->GetLastCommittedURL(); 731 const GURL& browser_url = web_contents()->GetLastCommittedURL();
681 const std::string& mime_type = web_contents()->GetContentsMimeType(); 732 const std::string& mime_type = web_contents()->GetContentsMimeType();
682 DCHECK(!browser_url.is_empty()); 733 DCHECK(!browser_url.is_empty());
683 DCHECK(!mime_type.empty()); 734 DCHECK(!mime_type.empty());
684 committed_load_->set_renderer_tracked( 735 committed_load_->set_renderer_tracked(
685 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); 736 IsRelevantNavigation(navigation_handle, browser_url, mime_type));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 } 803 }
753 804
754 // If this is a crash, eagerly log the aborted provisional loads and the 805 // If this is a crash, eagerly log the aborted provisional loads and the
755 // committed load. |provisional_loads_| don't need to be destroyed here 806 // committed load. |provisional_loads_| don't need to be destroyed here
756 // because their lifetime is tied to the NavigationHandle. 807 // because their lifetime is tied to the NavigationHandle.
757 committed_load_.reset(); 808 committed_load_.reset();
758 aborted_provisional_loads_.clear(); 809 aborted_provisional_loads_.clear();
759 } 810 }
760 811
761 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { 812 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) {
762 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now()); 813 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true);
763 } 814 }
764 815
765 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( 816 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
766 UserAbortType abort_type, 817 UserAbortType abort_type,
767 base::TimeTicks timestamp) { 818 base::TimeTicks timestamp,
819 bool is_certainly_browser_timestamp) {
768 if (committed_load_) 820 if (committed_load_)
769 committed_load_->NotifyAbort(abort_type, timestamp); 821 committed_load_->NotifyAbort(abort_type, timestamp,
822 is_certainly_browser_timestamp);
770 for (const auto& kv : provisional_loads_) { 823 for (const auto& kv : provisional_loads_) {
771 kv.second->NotifyAbort(abort_type, timestamp); 824 kv.second->NotifyAbort(abort_type, timestamp,
825 is_certainly_browser_timestamp);
772 } 826 }
773 for (const auto& tracker : aborted_provisional_loads_) { 827 for (const auto& tracker : aborted_provisional_loads_) {
774 if (tracker->IsLikelyProvisionalAbort(timestamp)) 828 if (tracker->IsLikelyProvisionalAbort(timestamp))
775 tracker->UpdateAbort(abort_type, timestamp); 829 tracker->UpdateAbort(abort_type, timestamp,
830 is_certainly_browser_timestamp);
776 } 831 }
777 aborted_provisional_loads_.clear(); 832 aborted_provisional_loads_.clear();
778 } 833 }
779 834
780 std::unique_ptr<PageLoadTracker> 835 std::unique_ptr<PageLoadTracker>
781 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( 836 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
782 content::NavigationHandle* new_navigation) { 837 content::NavigationHandle* new_navigation) {
783 // If there are multiple aborted loads that can be attributed to this one, 838 // If there are multiple aborted loads that can be attributed to this one,
784 // just count the latest one for simplicity. Other loads will fall into the 839 // just count the latest one for simplicity. Other loads will fall into the
785 // OTHER bucket, though there shouldn't be very many. 840 // OTHER bucket, though there shouldn't be very many.
786 if (aborted_provisional_loads_.size() == 0) 841 if (aborted_provisional_loads_.size() == 0)
787 return nullptr; 842 return nullptr;
788 if (aborted_provisional_loads_.size() > 1) 843 if (aborted_provisional_loads_.size() > 1)
789 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); 844 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS);
790 845
791 std::unique_ptr<PageLoadTracker> last_aborted_load = 846 std::unique_ptr<PageLoadTracker> last_aborted_load =
792 std::move(aborted_provisional_loads_.back()); 847 std::move(aborted_provisional_loads_.back());
793 aborted_provisional_loads_.pop_back(); 848 aborted_provisional_loads_.pop_back();
794 849
795 base::TimeTicks timestamp = new_navigation->NavigationStart(); 850 base::TimeTicks timestamp = new_navigation->NavigationStart();
796 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) 851 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp))
797 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp); 852 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false);
798 853
799 aborted_provisional_loads_.clear(); 854 aborted_provisional_loads_.clear();
800 return last_aborted_load; 855 return last_aborted_load;
801 } 856 }
802 857
803 void MetricsWebContentsObserver::OnTimingUpdated( 858 void MetricsWebContentsObserver::OnTimingUpdated(
804 content::RenderFrameHost* render_frame_host, 859 content::RenderFrameHost* render_frame_host,
805 const PageLoadTiming& timing, 860 const PageLoadTiming& timing,
806 const PageLoadMetadata& metadata) { 861 const PageLoadMetadata& metadata) {
807 bool error = false; 862 bool error = false;
(...skipping 22 matching lines...) Expand all
830 885
831 if (!committed_load_->UpdateTiming(timing, metadata)) { 886 if (!committed_load_->UpdateTiming(timing, metadata)) {
832 // If the page load tracker cannot update its timing, something is wrong 887 // If the page load tracker cannot update its timing, something is wrong
833 // with the IPC (it's from another load, or it's invalid in some other way). 888 // with the IPC (it's from another load, or it's invalid in some other way).
834 // We expect this to be a rare occurrence. 889 // We expect this to be a rare occurrence.
835 RecordInternalError(ERR_BAD_TIMING_IPC); 890 RecordInternalError(ERR_BAD_TIMING_IPC);
836 } 891 }
837 } 892 }
838 893
839 } // namespace page_load_metrics 894 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698