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

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, Fixed non-deterministic tests and Bryan's review comments. Created 4 years, 7 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 aborted_chain_size_same_url_(aborted_chain_size_same_url), 251 aborted_chain_size_same_url_(aborted_chain_size_same_url),
252 embedder_interface_(embedder_interface) { 252 embedder_interface_(embedder_interface) {
253 DCHECK(!navigation_handle->HasCommitted()); 253 DCHECK(!navigation_handle->HasCommitted());
254 embedder_interface_->RegisterObservers(this); 254 embedder_interface_->RegisterObservers(this);
255 for (const auto& observer : observers_) { 255 for (const auto& observer : observers_) {
256 observer->OnStart(navigation_handle, currently_committed_url); 256 observer->OnStart(navigation_handle, currently_committed_url);
257 } 257 }
258 } 258 }
259 259
260 PageLoadTracker::~PageLoadTracker() { 260 PageLoadTracker::~PageLoadTracker() {
261 const PageLoadExtraInfo info = GetPageLoadMetricsInfo(); 261 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
262 if (!info.time_to_commit.is_zero() && renderer_tracked() && 262
263 timing_.IsEmpty()) { 263 if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) {
264 RecordInternalError(ERR_NO_IPCS_RECEIVED); 264 RecordInternalError(ERR_NO_IPCS_RECEIVED);
265 } 265 }
266 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their 266 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
267 // chain length added to the next navigation. Take care not to double count 267 // chain length added to the next navigation. Take care not to double count
268 // them. Also do not double count committed loads, which call this already. 268 // them. Also do not double count committed loads, which call this already.
269 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) 269 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION)
270 LogAbortChainHistograms(nullptr); 270 LogAbortChainHistograms(nullptr);
271 271
272 for (const auto& observer : observers_) { 272 for (const auto& observer : observers_) {
273 observer->OnComplete(timing_, info); 273 observer->OnComplete(timing_, info);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 default: 314 default:
315 NOTREACHED() 315 NOTREACHED()
316 << "LogAbortChainHistograms received unexpected ui::PageTransition: " 316 << "LogAbortChainHistograms received unexpected ui::PageTransition: "
317 << committed_transition; 317 << committed_transition;
318 return; 318 return;
319 } 319 }
320 } 320 }
321 321
322 void PageLoadTracker::WebContentsHidden() { 322 void PageLoadTracker::WebContentsHidden() {
323 // Only log the first time we background in a given page load. 323 // Only log the first time we background in a given page load.
324 if (background_time_.is_null()) { 324 if (!background_time_.is_null()) {
Charlie Harrison 2016/05/19 18:20:49 Why not convert fg and bg time to optionals too? U
shivanisha 2016/05/23 15:06:43 Either way is fine, Since TimeTicks has the semant
325 // Make sure we either started in the foreground and haven't been 325 return;
326 // foregrounded yet, or started in the background and have already been
327 // foregrounded.
328 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
329 background_time_ = base::TimeTicks::Now();
330 } 326 }
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
329 // foregrounded.
330 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
331 background_time_ = base::TimeTicks::Now();
332 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
331 } 333 }
332 334
333 void PageLoadTracker::WebContentsShown() { 335 void PageLoadTracker::WebContentsShown() {
334 // Only log the first time we foreground in a given page load. 336 // Only log the first time we foreground in a given page load.
335 if (foreground_time_.is_null()) { 337 if (!foreground_time_.is_null()) {
336 // Make sure we either started in the background and haven't been 338 return;
337 // backgrounded yet, or started in the foreground and have already been
338 // backgrounded.
339 DCHECK_NE(started_in_foreground_, background_time_.is_null());
340 foreground_time_ = base::TimeTicks::Now();
341 } 339 }
340 // Make sure we either started in the background and haven't been
341 // backgrounded yet, or started in the foreground and have already been
342 // backgrounded.
343 DCHECK_NE(started_in_foreground_, background_time_.is_null());
344 foreground_time_ = base::TimeTicks::Now();
345 ClampBrowserTimestampIfInterProcessTimeTickSkew(&foreground_time_);
342 } 346 }
343 347
344 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { 348 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) {
345 // TODO(bmcquade): To improve accuracy, consider adding commit time to 349 // TODO(bmcquade): To improve accuracy, consider adding commit time to
346 // NavigationHandle. Taking a timestamp here should be close enough for now. 350 // NavigationHandle. Taking a timestamp here should be close enough for now.
347 commit_time_ = base::TimeTicks::Now(); 351 commit_time_ = base::TimeTicks::Now();
352 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_);
348 url_ = navigation_handle->GetURL(); 353 url_ = navigation_handle->GetURL();
349 for (const auto& observer : observers_) { 354 for (const auto& observer : observers_) {
350 observer->OnCommit(navigation_handle); 355 observer->OnCommit(navigation_handle);
351 } 356 }
352 LogAbortChainHistograms(navigation_handle); 357 LogAbortChainHistograms(navigation_handle);
353 } 358 }
354 359
355 void PageLoadTracker::FailedProvisionalLoad( 360 void PageLoadTracker::FailedProvisionalLoad(
356 content::NavigationHandle* navigation_handle) { 361 content::NavigationHandle* navigation_handle) {
357 for (const auto& observer : observers_) { 362 for (const auto& observer : observers_) {
(...skipping 24 matching lines...) Expand all
382 valid_behavior_descendent) { 387 valid_behavior_descendent) {
383 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() 388 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo()
384 // must be called before DispatchObserverTimingCallbacks, but its 389 // must be called before DispatchObserverTimingCallbacks, but its
385 // implementation depends on the state of metadata_, so we need to update 390 // implementation depends on the state of metadata_, so we need to update
386 // metadata_ before calling GetPageLoadMetricsInfo. Thus, we make a copy of 391 // metadata_ before calling GetPageLoadMetricsInfo. Thus, we make a copy of
387 // timing here, update timing_ and metadata_, and then proceed to dispatch 392 // timing here, update timing_ and metadata_, and then proceed to dispatch
388 // the observer timing callbacks. 393 // the observer timing callbacks.
389 const PageLoadTiming last_timing = timing_; 394 const PageLoadTiming last_timing = timing_;
390 timing_ = new_timing; 395 timing_ = new_timing;
391 metadata_ = new_metadata; 396 metadata_ = new_metadata;
392 const PageLoadExtraInfo info = GetPageLoadMetricsInfo(); 397 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
393 for (const auto& observer : observers_) { 398 for (const auto& observer : observers_) {
394 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, 399 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing,
395 info); 400 info);
396 } 401 }
397 return true; 402 return true;
398 } 403 }
399 return false; 404 return false;
400 } 405 }
401 406
402 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) { 407 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) {
403 renderer_tracked_ = renderer_tracked; 408 renderer_tracked_ = renderer_tracked;
404 } 409 }
405 410
406 void PageLoadTracker::AddObserver( 411 void PageLoadTracker::AddObserver(
407 std::unique_ptr<PageLoadMetricsObserver> observer) { 412 std::unique_ptr<PageLoadMetricsObserver> observer) {
408 observers_.push_back(std::move(observer)); 413 observers_.push_back(std::move(observer));
409 } 414 }
410 415
411 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { 416 void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew(
412 base::TimeDelta first_background_time; 417 base::TimeTicks* event_time) {
413 base::TimeDelta first_foreground_time; 418 // Windows 10 GCE bot non-deterministically failed because
Charlie Harrison 2016/05/19 18:20:49 Looks like you can fit more words on this line.
shivanisha 2016/05/23 15:06:43 done
414 base::TimeDelta time_to_abort; 419 // TimeTicks::Now() called in the browser process e.g. for commit_time
415 base::TimeDelta time_to_commit; 420 // was lesser than navigation_start_ that was populated in the renderer
Charlie Harrison 2016/05/19 18:20:49 s/lesser/less
shivanisha 2016/05/23 15:06:43 done
416 if (!background_time_.is_null()) 421 // process because the clock was not system-wide monotonic.
422
423 // TODO (shivanisha) Currently IsHighResolution is the best way to check
424 // if the clock is system-wide monotonic. However IsHighResolution
425 // does a broader check to see if the clock in use is high resolution
426 // which also implies it is system-wide monotonic (on Windows).
Charlie Harrison 2016/05/19 18:20:48 Are you sure this check is always correct in findi
shivanisha 2016/05/23 15:06:43 That's how it is currently implemented on Windows.
427 if (base::TimeTicks::IsHighResolution()) {
428 return;
429 }
430
431 if (!event_time->is_null() && *event_time < navigation_start_) {
432 UMA_HISTOGRAM_ENUMERATION(internal::kErrorEvents,
433 ERR_INTER_PROCESS_TIME_TICK_SKEW, ERR_LAST_ENTRY);
434 *event_time = navigation_start_;
435 }
436 }
437
438 PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() {
439 base::Optional<base::TimeDelta> first_background_time;
440 base::Optional<base::TimeDelta> first_foreground_time;
441 base::Optional<base::TimeDelta> time_to_abort;
442 base::Optional<base::TimeDelta> time_to_commit;
443
444 if (!background_time_.is_null()) {
445 DCHECK_GE(background_time_, navigation_start_);
417 first_background_time = background_time_ - navigation_start_; 446 first_background_time = background_time_ - navigation_start_;
418 if (!foreground_time_.is_null()) 447 }
448
449 if (!foreground_time_.is_null()) {
450 DCHECK_GE(foreground_time_, navigation_start_);
419 first_foreground_time = foreground_time_ - navigation_start_; 451 first_foreground_time = foreground_time_ - navigation_start_;
452 }
453
420 if (abort_type_ != ABORT_NONE) { 454 if (abort_type_ != ABORT_NONE) {
421 DCHECK_GT(abort_time_, navigation_start_); 455 DCHECK_GE(abort_time_, navigation_start_);
422 time_to_abort = abort_time_ - navigation_start_; 456 time_to_abort = abort_time_ - navigation_start_;
423 } else { 457 } else {
424 DCHECK(abort_time_.is_null()); 458 DCHECK(abort_time_.is_null());
425 } 459 }
426 460
427 if (!commit_time_.is_null()) { 461 if (!commit_time_.is_null()) {
428 DCHECK_GT(commit_time_, navigation_start_); 462 DCHECK_GE(commit_time_, navigation_start_);
429 time_to_commit = commit_time_ - navigation_start_; 463 time_to_commit = commit_time_ - navigation_start_;
430 } else {
431 DCHECK(commit_time_.is_null());
432 } 464 }
465
433 return PageLoadExtraInfo( 466 return PageLoadExtraInfo(
434 first_background_time, first_foreground_time, started_in_foreground_, 467 first_background_time, first_foreground_time, started_in_foreground_,
435 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_, 468 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_,
436 time_to_abort, metadata_); 469 time_to_abort, metadata_);
437 } 470 }
438 471
439 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, 472 void PageLoadTracker::NotifyAbort(UserAbortType abort_type,
440 base::TimeTicks timestamp) { 473 base::TimeTicks timestamp,
474 bool is_browser_timetick) {
441 DCHECK_NE(abort_type, ABORT_NONE); 475 DCHECK_NE(abort_type, ABORT_NONE);
442 // Use UpdateAbort to update an already notified PageLoadTracker. 476 // Use UpdateAbort to update an already notified PageLoadTracker.
443 if (abort_type_ != ABORT_NONE) 477 if (abort_type_ != ABORT_NONE)
444 return; 478 return;
445 479
446 UpdateAbortInternal(abort_type, timestamp); 480 UpdateAbortInternal(abort_type, timestamp, is_browser_timetick);
447 } 481 }
448 482
449 void PageLoadTracker::UpdateAbort(UserAbortType abort_type, 483 void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
450 base::TimeTicks timestamp) { 484 base::TimeTicks timestamp,
485 bool is_browser_timetick) {
451 DCHECK_NE(abort_type, ABORT_NONE); 486 DCHECK_NE(abort_type, ABORT_NONE);
452 DCHECK_NE(abort_type, ABORT_OTHER); 487 DCHECK_NE(abort_type, ABORT_OTHER);
453 DCHECK_EQ(abort_type_, ABORT_OTHER); 488 DCHECK_EQ(abort_type_, ABORT_OTHER);
454 489
455 // For some aborts (e.g. navigations), the initiated timestamp can be earlier 490 // For some aborts (e.g. navigations), the initiated timestamp can be earlier
456 // than the timestamp that aborted the load. Taking the minimum gives the 491 // than the timestamp that aborted the load. Taking the minimum gives the
457 // closest user initiated time known. 492 // closest user initiated time known.
458 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp)); 493 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp),
494 is_browser_timetick);
459 } 495 }
460 496
461 bool PageLoadTracker::IsLikelyProvisionalAbort( 497 bool PageLoadTracker::IsLikelyProvisionalAbort(
462 base::TimeTicks abort_cause_time) { 498 base::TimeTicks abort_cause_time) {
463 // Note that |abort_cause_time - abort_time| can be negative. 499 // Note that |abort_cause_time - abort_time| can be negative.
464 return abort_type_ == ABORT_OTHER && 500 return abort_type_ == ABORT_OTHER &&
465 (abort_cause_time - abort_time_).InMilliseconds() < 100; 501 (abort_cause_time - abort_time_).InMilliseconds() < 100;
466 } 502 }
467 503
468 bool PageLoadTracker::MatchesOriginalNavigation( 504 bool PageLoadTracker::MatchesOriginalNavigation(
469 content::NavigationHandle* navigation_handle) { 505 content::NavigationHandle* navigation_handle) {
470 // Neither navigation should have committed. 506 // Neither navigation should have committed.
471 DCHECK(!navigation_handle->HasCommitted()); 507 DCHECK(!navigation_handle->HasCommitted());
472 DCHECK(commit_time_.is_null()); 508 DCHECK(commit_time_.is_null());
473 return navigation_handle->GetURL() == url_; 509 return navigation_handle->GetURL() == url_;
474 } 510 }
475 511
476 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type, 512 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
477 base::TimeTicks timestamp) { 513 base::TimeTicks timestamp,
514 bool is_browser_timetick) {
478 // When a provisional navigation commits, that navigation's start time is 515 // When a provisional navigation commits, that navigation's start time is
479 // interpreted as the abort time for other provisional loads in the tab. 516 // interpreted as the abort time for other provisional loads in the tab.
480 // However, this only makes sense if the committed load started after the 517 // However, this only makes sense if the committed load started after the
481 // aborted provisional loads started. Thus we ignore cases where the committed 518 // aborted provisional loads started. Thus we ignore cases where the committed
482 // load started before the aborted provisional load, as this would result in 519 // load started before the aborted provisional load, as this would result in
483 // recording a negative time-to-abort. The real issue here is that we have to 520 // recording a negative time-to-abort. The real issue here is that we have to
484 // infer the cause of aborts. It would be better if the navigation code could 521 // infer the cause of aborts. It would be better if the navigation code could
485 // instead report the actual cause of an aborted navigation. See crbug/571647 522 // instead report the actual cause of an aborted navigation. See crbug/571647
486 // for details. 523 // for details.
487 if (timestamp <= navigation_start_) { 524 if (timestamp < navigation_start_) {
488 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); 525 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START);
489 abort_type_ = ABORT_NONE; 526 abort_type_ = ABORT_NONE;
490 abort_time_ = base::TimeTicks(); 527 abort_time_ = base::TimeTicks();
491 return; 528 return;
492 } 529 }
493 abort_type_ = abort_type; 530 abort_type_ = abort_type;
494 abort_time_ = timestamp; 531 abort_time_ = timestamp;
532
533 if (is_browser_timetick) {
534 ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_);
535 }
495 } 536 }
496 537
497 // static 538 // static
498 MetricsWebContentsObserver::MetricsWebContentsObserver( 539 MetricsWebContentsObserver::MetricsWebContentsObserver(
499 content::WebContents* web_contents, 540 content::WebContents* web_contents,
500 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) 541 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface)
501 : content::WebContentsObserver(web_contents), 542 : content::WebContentsObserver(web_contents),
502 in_foreground_(false), 543 in_foreground_(false),
503 embedder_interface_(std::move(embedder_interface)), 544 embedder_interface_(std::move(embedder_interface)),
504 has_navigated_(false) {} 545 has_navigated_(false) {}
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // the MetricsWebContentsObserver owns them both list and they are torn down 621 // the MetricsWebContentsObserver owns them both list and they are torn down
581 // after the PageLoadTracker. The PageLoadTracker does not hold on to 622 // after the PageLoadTracker. The PageLoadTracker does not hold on to
582 // committed_load_ or navigation_handle beyond the scope of the constructor. 623 // committed_load_ or navigation_handle beyond the scope of the constructor.
583 provisional_loads_.insert(std::make_pair( 624 provisional_loads_.insert(std::make_pair(
584 navigation_handle, 625 navigation_handle,
585 base::WrapUnique(new PageLoadTracker( 626 base::WrapUnique(new PageLoadTracker(
586 in_foreground_, embedder_interface_.get(), currently_committed_url, 627 in_foreground_, embedder_interface_.get(), currently_committed_url,
587 navigation_handle, chain_size, chain_size_same_url)))); 628 navigation_handle, chain_size, chain_size_same_url))));
588 } 629 }
589 630
631 const PageLoadExtraInfo
632 MetricsWebContentsObserver::GetPageLoadExtraInfoCommittedLoad() {
633 DCHECK(committed_load_);
634 return committed_load_->ComputePageLoadExtraInfo();
635 }
636
590 void MetricsWebContentsObserver::DidFinishNavigation( 637 void MetricsWebContentsObserver::DidFinishNavigation(
591 content::NavigationHandle* navigation_handle) { 638 content::NavigationHandle* navigation_handle) {
592 if (!navigation_handle->IsInMainFrame()) 639 if (!navigation_handle->IsInMainFrame())
593 return; 640 return;
594 641
595 std::unique_ptr<PageLoadTracker> finished_nav( 642 std::unique_ptr<PageLoadTracker> finished_nav(
596 std::move(provisional_loads_[navigation_handle])); 643 std::move(provisional_loads_[navigation_handle]));
597 provisional_loads_.erase(navigation_handle); 644 provisional_loads_.erase(navigation_handle);
598 645
599 // There's a chance a navigation could have started before we were added to a 646 // There's a chance a navigation could have started before we were added to a
(...skipping 12 matching lines...) Expand all
612 net::Error error = navigation_handle->GetNetErrorCode(); 659 net::Error error = navigation_handle->GetNetErrorCode();
613 660
614 // net::OK: This case occurs when the NavigationHandle finishes and reports 661 // net::OK: This case occurs when the NavigationHandle finishes and reports
615 // !HasCommitted(), but reports no net::Error. This should not occur 662 // !HasCommitted(), but reports no net::Error. This should not occur
616 // pre-PlzNavigate, but afterwards it should represent the navigation 663 // pre-PlzNavigate, but afterwards it should represent the navigation
617 // stopped by the user before it was ready to commit. 664 // stopped by the user before it was ready to commit.
618 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED. 665 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED.
619 // Note that this can come from some non user-initiated errors, such as 666 // Note that this can come from some non user-initiated errors, such as
620 // downloads, or 204 responses. See crbug.com/542369. 667 // downloads, or 204 responses. See crbug.com/542369.
621 if ((error == net::OK) || (error == net::ERR_ABORTED)) { 668 if ((error == net::OK) || (error == net::ERR_ABORTED)) {
622 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now()); 669 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true);
623 aborted_provisional_loads_.push_back(std::move(finished_nav)); 670 aborted_provisional_loads_.push_back(std::move(finished_nav));
624 } 671 }
625 672
626 return; 673 return;
627 } 674 }
628 675
629 // Don't treat a same-page nav as a new page load. 676 // Don't treat a same-page nav as a new page load.
630 if (navigation_handle->IsSamePage()) 677 if (navigation_handle->IsSamePage())
631 return; 678 return;
632 679
633 // Notify other loads that they may have been aborted by this committed load. 680 // Notify other loads that they may have been aborted by this committed load.
634 // Note that by using the committed navigation start as the abort cause, we 681 // Note that by using the committed navigation start as the abort cause, we
635 // lose data on provisional loads that were aborted by other provisional 682 // lose data on provisional loads that were aborted by other provisional
636 // loads. Those will either be listed as ABORT_OTHER or as being aborted by 683 // loads. Those will either be listed as ABORT_OTHER or as being aborted by
637 // this load. 684 // this load.
638 NotifyAbortAllLoadsWithTimestamp( 685 NotifyAbortAllLoadsWithTimestamp(
639 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), 686 AbortTypeForPageTransition(navigation_handle->GetPageTransition()),
640 navigation_handle->NavigationStart()); 687 navigation_handle->NavigationStart(), false);
641 688
642 committed_load_ = std::move(finished_nav); 689 committed_load_ = std::move(finished_nav);
643 aborted_provisional_loads_.clear(); 690 aborted_provisional_loads_.clear();
644 691
645 const GURL& browser_url = web_contents()->GetLastCommittedURL(); 692 const GURL& browser_url = web_contents()->GetLastCommittedURL();
646 const std::string& mime_type = web_contents()->GetContentsMimeType(); 693 const std::string& mime_type = web_contents()->GetContentsMimeType();
647 DCHECK(!browser_url.is_empty()); 694 DCHECK(!browser_url.is_empty());
648 DCHECK(!mime_type.empty()); 695 DCHECK(!mime_type.empty());
649 committed_load_->set_renderer_tracked( 696 committed_load_->set_renderer_tracked(
650 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); 697 IsRelevantNavigation(navigation_handle, browser_url, mime_type));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 } 750 }
704 751
705 // If this is a crash, eagerly log the aborted provisional loads and the 752 // If this is a crash, eagerly log the aborted provisional loads and the
706 // committed load. |provisional_loads_| don't need to be destroyed here 753 // committed load. |provisional_loads_| don't need to be destroyed here
707 // because their lifetime is tied to the NavigationHandle. 754 // because their lifetime is tied to the NavigationHandle.
708 committed_load_.reset(); 755 committed_load_.reset();
709 aborted_provisional_loads_.clear(); 756 aborted_provisional_loads_.clear();
710 } 757 }
711 758
712 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { 759 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) {
713 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now()); 760 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true);
714 } 761 }
715 762
716 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( 763 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
717 UserAbortType abort_type, 764 UserAbortType abort_type,
718 base::TimeTicks timestamp) { 765 base::TimeTicks timestamp,
766 bool is_browser_timetick) {
719 if (committed_load_) 767 if (committed_load_)
720 committed_load_->NotifyAbort(abort_type, timestamp); 768 committed_load_->NotifyAbort(abort_type, timestamp, is_browser_timetick);
721 for (const auto& kv : provisional_loads_) { 769 for (const auto& kv : provisional_loads_) {
722 kv.second->NotifyAbort(abort_type, timestamp); 770 kv.second->NotifyAbort(abort_type, timestamp, is_browser_timetick);
723 } 771 }
724 for (const auto& tracker : aborted_provisional_loads_) { 772 for (const auto& tracker : aborted_provisional_loads_) {
725 if (tracker->IsLikelyProvisionalAbort(timestamp)) 773 if (tracker->IsLikelyProvisionalAbort(timestamp))
726 tracker->UpdateAbort(abort_type, timestamp); 774 tracker->UpdateAbort(abort_type, timestamp, is_browser_timetick);
727 } 775 }
728 aborted_provisional_loads_.clear(); 776 aborted_provisional_loads_.clear();
729 } 777 }
730 778
731 std::unique_ptr<PageLoadTracker> 779 std::unique_ptr<PageLoadTracker>
732 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( 780 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation(
733 content::NavigationHandle* new_navigation) { 781 content::NavigationHandle* new_navigation) {
734 // If there are multiple aborted loads that can be attributed to this one, 782 // If there are multiple aborted loads that can be attributed to this one,
735 // just count the latest one for simplicity. Other loads will fall into the 783 // just count the latest one for simplicity. Other loads will fall into the
736 // OTHER bucket, though there shouldn't be very many. 784 // OTHER bucket, though there shouldn't be very many.
737 if (aborted_provisional_loads_.size() == 0) 785 if (aborted_provisional_loads_.size() == 0)
738 return nullptr; 786 return nullptr;
739 if (aborted_provisional_loads_.size() > 1) 787 if (aborted_provisional_loads_.size() > 1)
740 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); 788 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS);
741 789
742 std::unique_ptr<PageLoadTracker> last_aborted_load = 790 std::unique_ptr<PageLoadTracker> last_aborted_load =
743 std::move(aborted_provisional_loads_.back()); 791 std::move(aborted_provisional_loads_.back());
744 aborted_provisional_loads_.pop_back(); 792 aborted_provisional_loads_.pop_back();
745 793
746 base::TimeTicks timestamp = new_navigation->NavigationStart(); 794 base::TimeTicks timestamp = new_navigation->NavigationStart();
747 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) 795 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp))
748 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp); 796 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false);
749 797
750 aborted_provisional_loads_.clear(); 798 aborted_provisional_loads_.clear();
751 return last_aborted_load; 799 return last_aborted_load;
752 } 800 }
753 801
754 void MetricsWebContentsObserver::OnTimingUpdated( 802 void MetricsWebContentsObserver::OnTimingUpdated(
755 content::RenderFrameHost* render_frame_host, 803 content::RenderFrameHost* render_frame_host,
756 const PageLoadTiming& timing, 804 const PageLoadTiming& timing,
757 const PageLoadMetadata& metadata) { 805 const PageLoadMetadata& metadata) {
758 bool error = false; 806 bool error = false;
(...skipping 22 matching lines...) Expand all
781 829
782 if (!committed_load_->UpdateTiming(timing, metadata)) { 830 if (!committed_load_->UpdateTiming(timing, metadata)) {
783 // If the page load tracker cannot update its timing, something is wrong 831 // If the page load tracker cannot update its timing, something is wrong
784 // with the IPC (it's from another load, or it's invalid in some other way). 832 // with the IPC (it's from another load, or it's invalid in some other way).
785 // We expect this to be a rare occurrence. 833 // We expect this to be a rare occurrence.
786 RecordInternalError(ERR_BAD_TIMING_IPC); 834 RecordInternalError(ERR_BAD_TIMING_IPC);
787 } 835 }
788 } 836 }
789 837
790 } // namespace page_load_metrics 838 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698