Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 aborted_chain_size_same_url_(aborted_chain_size_same_url), | 221 aborted_chain_size_same_url_(aborted_chain_size_same_url), |
| 222 embedder_interface_(embedder_interface) { | 222 embedder_interface_(embedder_interface) { |
| 223 DCHECK(!navigation_handle->HasCommitted()); | 223 DCHECK(!navigation_handle->HasCommitted()); |
| 224 embedder_interface_->RegisterObservers(this); | 224 embedder_interface_->RegisterObservers(this); |
| 225 for (const auto& observer : observers_) { | 225 for (const auto& observer : observers_) { |
| 226 observer->OnStart(navigation_handle, currently_committed_url); | 226 observer->OnStart(navigation_handle, currently_committed_url); |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 PageLoadTracker::~PageLoadTracker() { | 230 PageLoadTracker::~PageLoadTracker() { |
| 231 const PageLoadExtraInfo info = GetPageLoadMetricsInfo(); | 231 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); |
| 232 if (!info.time_to_commit.is_zero() && renderer_tracked() && | 232 |
| 233 timing_.IsEmpty()) { | 233 if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) { |
| 234 RecordInternalError(ERR_NO_IPCS_RECEIVED); | 234 RecordInternalError(ERR_NO_IPCS_RECEIVED); |
| 235 } | 235 } |
| 236 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their | 236 // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their |
| 237 // chain length added to the next navigation. Take care not to double count | 237 // chain length added to the next navigation. Take care not to double count |
| 238 // them. Also do not double count committed loads, which call this already. | 238 // them. Also do not double count committed loads, which call this already. |
| 239 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) | 239 if (commit_time_.is_null() && abort_type_ != ABORT_UNKNOWN_NAVIGATION) |
| 240 LogAbortChainHistograms(nullptr); | 240 LogAbortChainHistograms(nullptr); |
| 241 | 241 |
| 242 for (const auto& observer : observers_) { | 242 for (const auto& observer : observers_) { |
| 243 observer->OnComplete(timing_, info); | 243 observer->OnComplete(timing_, info); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 default: | 284 default: |
| 285 NOTREACHED() | 285 NOTREACHED() |
| 286 << "LogAbortChainHistograms received unexpected ui::PageTransition: " | 286 << "LogAbortChainHistograms received unexpected ui::PageTransition: " |
| 287 << committed_transition; | 287 << committed_transition; |
| 288 return; | 288 return; |
| 289 } | 289 } |
| 290 } | 290 } |
| 291 | 291 |
| 292 void PageLoadTracker::WebContentsHidden() { | 292 void PageLoadTracker::WebContentsHidden() { |
| 293 // Only log the first time we background in a given page load. | 293 // Only log the first time we background in a given page load. |
| 294 if (background_time_.is_null()) { | 294 if (!background_time_.is_null()) { |
| 295 // Make sure we either started in the foreground and haven't been | 295 return; |
| 296 // foregrounded yet, or started in the background and have already been | |
| 297 // foregrounded. | |
| 298 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null()); | |
| 299 background_time_ = base::TimeTicks::Now(); | |
| 300 } | 296 } |
| 297 // Make sure we either started in the foreground and haven't been | |
| 298 // foregrounded yet, or started in the background and have already been | |
| 299 // foregrounded. | |
| 300 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null()); | |
| 301 background_time_ = base::TimeTicks::Now(); | |
| 302 #if defined(OS_WIN) | |
| 303 RebaseBrowserTimestampIfInterProcessTimeTickSkew(background_time_); | |
| 304 #endif | |
| 301 } | 305 } |
| 302 | 306 |
| 303 void PageLoadTracker::WebContentsShown() { | 307 void PageLoadTracker::WebContentsShown() { |
| 304 // Only log the first time we foreground in a given page load. | 308 // Only log the first time we foreground in a given page load. |
| 305 if (foreground_time_.is_null()) { | 309 if (!foreground_time_.is_null()) { |
| 306 // Make sure we either started in the background and haven't been | 310 return; |
| 307 // backgrounded yet, or started in the foreground and have already been | |
| 308 // backgrounded. | |
| 309 DCHECK_NE(started_in_foreground_, background_time_.is_null()); | |
| 310 foreground_time_ = base::TimeTicks::Now(); | |
| 311 } | 311 } |
| 312 // Make sure we either started in the background and haven't been | |
| 313 // backgrounded yet, or started in the foreground and have already been | |
| 314 // backgrounded. | |
| 315 DCHECK_NE(started_in_foreground_, background_time_.is_null()); | |
| 316 foreground_time_ = base::TimeTicks::Now(); | |
| 317 #if defined(OS_WIN) | |
| 318 RebaseBrowserTimestampIfInterProcessTimeTickSkew(foreground_time_); | |
| 319 #endif | |
| 312 } | 320 } |
| 313 | 321 |
| 314 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { | 322 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { |
| 315 // TODO(bmcquade): To improve accuracy, consider adding commit time to | 323 // TODO(bmcquade): To improve accuracy, consider adding commit time to |
| 316 // NavigationHandle. Taking a timestamp here should be close enough for now. | 324 // NavigationHandle. Taking a timestamp here should be close enough for now. |
| 317 commit_time_ = base::TimeTicks::Now(); | 325 commit_time_ = base::TimeTicks::Now(); |
| 326 #if defined(OS_WIN) | |
| 327 RebaseBrowserTimestampIfInterProcessTimeTickSkew(commit_time_); | |
| 328 #endif | |
| 318 url_ = navigation_handle->GetURL(); | 329 url_ = navigation_handle->GetURL(); |
| 319 for (const auto& observer : observers_) { | 330 for (const auto& observer : observers_) { |
| 320 observer->OnCommit(navigation_handle); | 331 observer->OnCommit(navigation_handle); |
| 321 } | 332 } |
| 322 LogAbortChainHistograms(navigation_handle); | 333 LogAbortChainHistograms(navigation_handle); |
| 323 } | 334 } |
| 324 | 335 |
| 325 void PageLoadTracker::FailedProvisionalLoad( | 336 void PageLoadTracker::FailedProvisionalLoad( |
| 326 content::NavigationHandle* navigation_handle) { | 337 content::NavigationHandle* navigation_handle) { |
| 327 for (const auto& observer : observers_) { | 338 for (const auto& observer : observers_) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 | 370 |
| 360 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) { | 371 void PageLoadTracker::set_renderer_tracked(bool renderer_tracked) { |
| 361 renderer_tracked_ = renderer_tracked; | 372 renderer_tracked_ = renderer_tracked; |
| 362 } | 373 } |
| 363 | 374 |
| 364 void PageLoadTracker::AddObserver( | 375 void PageLoadTracker::AddObserver( |
| 365 std::unique_ptr<PageLoadMetricsObserver> observer) { | 376 std::unique_ptr<PageLoadMetricsObserver> observer) { |
| 366 observers_.push_back(std::move(observer)); | 377 observers_.push_back(std::move(observer)); |
| 367 } | 378 } |
| 368 | 379 |
| 369 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { | 380 #if defined(OS_WIN) |
| 370 base::TimeDelta first_background_time; | 381 void PageLoadTracker::RebaseBrowserTimestampIfInterProcessTimeTickSkew( |
| 371 base::TimeDelta first_foreground_time; | 382 base::TimeTicks& event_time) { |
|
Bryan McQuade
2016/05/02 18:32:40
style guide wants 'out' params (or inout params) t
shivanisha
2016/05/18 17:36:39
done.
| |
| 372 base::TimeDelta time_to_abort; | 383 // Windows 10 GCE bot non-deterministically failed because |
| 373 base::TimeDelta time_to_commit; | 384 // TimeTicks::Now() called in the browser process e.g. for commit_time |
| 374 if (!background_time_.is_null()) | 385 // was lesser than navigation_start_ that was populated in the renderer |
| 386 // process because the clock was not system-wide monotonic. | |
| 387 | |
| 388 // TODO (shivanisha) Currently IsHighResolution is the best way to check | |
| 389 // if the clock is system-wide monotonic. However IsHighResolution | |
| 390 // does a broader check to see if the clock in use is high resolution | |
| 391 // which also implies it is system-wide monotonic (on Windows). | |
| 392 if (base::TimeTicks::IsHighResolution()) { | |
| 393 return; | |
| 394 } | |
| 395 | |
| 396 if (!event_time.is_null() && event_time < navigation_start_) { | |
| 397 event_time = navigation_start_; | |
|
Bryan McQuade
2016/05/02 18:32:40
if we still have some kind of uma counter for erro
shivanisha
2016/05/18 17:36:39
done. Added a new enumeration for this case.
| |
| 398 } | |
| 399 } | |
| 400 #endif | |
| 401 | |
| 402 PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() { | |
| 403 base::Optional<base::TimeDelta> first_background_time; | |
| 404 base::Optional<base::TimeDelta> first_foreground_time; | |
| 405 base::Optional<base::TimeDelta> time_to_abort; | |
| 406 base::Optional<base::TimeDelta> time_to_commit; | |
| 407 | |
| 408 if (!background_time_.is_null()) { | |
| 409 DCHECK_GE(background_time_, navigation_start_); | |
| 375 first_background_time = background_time_ - navigation_start_; | 410 first_background_time = background_time_ - navigation_start_; |
| 376 if (!foreground_time_.is_null()) | 411 } |
| 412 | |
| 413 if (!foreground_time_.is_null()) { | |
| 414 DCHECK_GE(foreground_time_, navigation_start_); | |
| 377 first_foreground_time = foreground_time_ - navigation_start_; | 415 first_foreground_time = foreground_time_ - navigation_start_; |
| 416 } | |
| 417 | |
| 378 if (abort_type_ != ABORT_NONE) { | 418 if (abort_type_ != ABORT_NONE) { |
| 379 DCHECK_GT(abort_time_, navigation_start_); | 419 DCHECK_GE(abort_time_, navigation_start_); |
| 380 time_to_abort = abort_time_ - navigation_start_; | 420 time_to_abort = abort_time_ - navigation_start_; |
| 381 } else { | 421 } else { |
| 382 DCHECK(abort_time_.is_null()); | 422 DCHECK(abort_time_.is_null()); |
| 383 } | 423 } |
| 384 | 424 |
| 385 if (!commit_time_.is_null()) { | 425 if (!commit_time_.is_null()) { |
| 386 DCHECK_GT(commit_time_, navigation_start_); | 426 DCHECK_GE(commit_time_, navigation_start_); |
| 387 time_to_commit = commit_time_ - navigation_start_; | 427 time_to_commit = commit_time_ - navigation_start_; |
| 388 } else { | |
| 389 DCHECK(commit_time_.is_null()); | |
| 390 } | 428 } |
| 429 | |
| 391 return PageLoadExtraInfo( | 430 return PageLoadExtraInfo( |
| 392 first_background_time, first_foreground_time, started_in_foreground_, | 431 first_background_time, first_foreground_time, started_in_foreground_, |
| 393 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_, | 432 commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_, |
| 394 time_to_abort, metadata_); | 433 time_to_abort, metadata_); |
| 395 } | 434 } |
| 396 | 435 |
| 397 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, | 436 void PageLoadTracker::NotifyAbort(UserAbortType abort_type, |
| 398 base::TimeTicks timestamp) { | 437 base::TimeTicks timestamp, |
| 438 bool is_browser_timetick) { | |
| 399 DCHECK_NE(abort_type, ABORT_NONE); | 439 DCHECK_NE(abort_type, ABORT_NONE); |
| 400 // Use UpdateAbort to update an already notified PageLoadTracker. | 440 // Use UpdateAbort to update an already notified PageLoadTracker. |
| 401 if (abort_type_ != ABORT_NONE) | 441 if (abort_type_ != ABORT_NONE) |
| 402 return; | 442 return; |
| 403 | 443 |
| 404 UpdateAbortInternal(abort_type, timestamp); | 444 UpdateAbortInternal(abort_type, timestamp, is_browser_timetick); |
| 405 } | 445 } |
| 406 | 446 |
| 407 void PageLoadTracker::UpdateAbort(UserAbortType abort_type, | 447 void PageLoadTracker::UpdateAbort(UserAbortType abort_type, |
| 408 base::TimeTicks timestamp) { | 448 base::TimeTicks timestamp, |
| 449 bool is_browser_timetick) { | |
| 409 DCHECK_NE(abort_type, ABORT_NONE); | 450 DCHECK_NE(abort_type, ABORT_NONE); |
| 410 DCHECK_NE(abort_type, ABORT_OTHER); | 451 DCHECK_NE(abort_type, ABORT_OTHER); |
| 411 DCHECK_EQ(abort_type_, ABORT_OTHER); | 452 DCHECK_EQ(abort_type_, ABORT_OTHER); |
| 412 | 453 |
| 413 // For some aborts (e.g. navigations), the initiated timestamp can be earlier | 454 // For some aborts (e.g. navigations), the initiated timestamp can be earlier |
| 414 // than the timestamp that aborted the load. Taking the minimum gives the | 455 // than the timestamp that aborted the load. Taking the minimum gives the |
| 415 // closest user initiated time known. | 456 // closest user initiated time known. |
| 416 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp)); | 457 UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp), |
| 458 is_browser_timetick); | |
| 417 } | 459 } |
| 418 | 460 |
| 419 bool PageLoadTracker::IsLikelyProvisionalAbort( | 461 bool PageLoadTracker::IsLikelyProvisionalAbort( |
| 420 base::TimeTicks abort_cause_time) { | 462 base::TimeTicks abort_cause_time) { |
| 421 // Note that |abort_cause_time - abort_time| can be negative. | 463 // Note that |abort_cause_time - abort_time| can be negative. |
| 422 return abort_type_ == ABORT_OTHER && | 464 return abort_type_ == ABORT_OTHER && |
| 423 (abort_cause_time - abort_time_).InMilliseconds() < 100; | 465 (abort_cause_time - abort_time_).InMilliseconds() < 100; |
| 424 } | 466 } |
| 425 | 467 |
| 426 bool PageLoadTracker::MatchesOriginalNavigation( | 468 bool PageLoadTracker::MatchesOriginalNavigation( |
| 427 content::NavigationHandle* navigation_handle) { | 469 content::NavigationHandle* navigation_handle) { |
| 428 // Neither navigation should have committed. | 470 // Neither navigation should have committed. |
| 429 DCHECK(!navigation_handle->HasCommitted()); | 471 DCHECK(!navigation_handle->HasCommitted()); |
| 430 DCHECK(commit_time_.is_null()); | 472 DCHECK(commit_time_.is_null()); |
| 431 return navigation_handle->GetURL() == url_; | 473 return navigation_handle->GetURL() == url_; |
| 432 } | 474 } |
| 433 | 475 |
| 434 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type, | 476 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type, |
| 435 base::TimeTicks timestamp) { | 477 base::TimeTicks timestamp, |
| 478 bool is_browser_timetick) { | |
| 436 // When a provisional navigation commits, that navigation's start time is | 479 // When a provisional navigation commits, that navigation's start time is |
| 437 // interpreted as the abort time for other provisional loads in the tab. | 480 // interpreted as the abort time for other provisional loads in the tab. |
| 438 // However, this only makes sense if the committed load started after the | 481 // However, this only makes sense if the committed load started after the |
| 439 // aborted provisional loads started. Thus we ignore cases where the committed | 482 // aborted provisional loads started. Thus we ignore cases where the committed |
| 440 // load started before the aborted provisional load, as this would result in | 483 // load started before the aborted provisional load, as this would result in |
| 441 // recording a negative time-to-abort. The real issue here is that we have to | 484 // recording a negative time-to-abort. The real issue here is that we have to |
| 442 // infer the cause of aborts. It would be better if the navigation code could | 485 // infer the cause of aborts. It would be better if the navigation code could |
| 443 // instead report the actual cause of an aborted navigation. See crbug/571647 | 486 // instead report the actual cause of an aborted navigation. See crbug/571647 |
| 444 // for details. | 487 // for details. |
| 445 if (timestamp <= navigation_start_) { | 488 if (timestamp < navigation_start_) { |
| 446 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); | 489 RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START); |
| 447 abort_type_ = ABORT_NONE; | 490 abort_type_ = ABORT_NONE; |
| 448 abort_time_ = base::TimeTicks(); | 491 abort_time_ = base::TimeTicks(); |
| 449 return; | 492 return; |
| 450 } | 493 } |
| 451 abort_type_ = abort_type; | 494 abort_type_ = abort_type; |
| 452 abort_time_ = timestamp; | 495 abort_time_ = timestamp; |
| 496 | |
| 497 if (is_browser_timetick) { | |
| 498 #if defined(OS_WIN) | |
| 499 RebaseBrowserTimestampIfInterProcessTimeTickSkew(abort_time_); | |
| 500 #endif | |
| 501 } | |
| 453 } | 502 } |
| 454 | 503 |
| 455 // static | 504 // static |
| 456 MetricsWebContentsObserver::MetricsWebContentsObserver( | 505 MetricsWebContentsObserver::MetricsWebContentsObserver( |
| 457 content::WebContents* web_contents, | 506 content::WebContents* web_contents, |
| 458 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) | 507 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) |
| 459 : content::WebContentsObserver(web_contents), | 508 : content::WebContentsObserver(web_contents), |
| 460 in_foreground_(false), | 509 in_foreground_(false), |
| 461 embedder_interface_(std::move(embedder_interface)), | 510 embedder_interface_(std::move(embedder_interface)), |
| 462 has_navigated_(false) {} | 511 has_navigated_(false) {} |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 net::Error error = navigation_handle->GetNetErrorCode(); | 619 net::Error error = navigation_handle->GetNetErrorCode(); |
| 571 | 620 |
| 572 // net::OK: This case occurs when the NavigationHandle finishes and reports | 621 // net::OK: This case occurs when the NavigationHandle finishes and reports |
| 573 // !HasCommitted(), but reports no net::Error. This should not occur | 622 // !HasCommitted(), but reports no net::Error. This should not occur |
| 574 // pre-PlzNavigate, but afterwards it should represent the navigation | 623 // pre-PlzNavigate, but afterwards it should represent the navigation |
| 575 // stopped by the user before it was ready to commit. | 624 // stopped by the user before it was ready to commit. |
| 576 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED. | 625 // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED. |
| 577 // Note that this can come from some non user-initiated errors, such as | 626 // Note that this can come from some non user-initiated errors, such as |
| 578 // downloads, or 204 responses. See crbug.com/542369. | 627 // downloads, or 204 responses. See crbug.com/542369. |
| 579 if ((error == net::OK) || (error == net::ERR_ABORTED)) { | 628 if ((error == net::OK) || (error == net::ERR_ABORTED)) { |
| 580 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now()); | 629 finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true); |
| 581 aborted_provisional_loads_.push_back(std::move(finished_nav)); | 630 aborted_provisional_loads_.push_back(std::move(finished_nav)); |
| 582 } | 631 } |
| 583 | 632 |
| 584 return; | 633 return; |
| 585 } | 634 } |
| 586 | 635 |
| 587 // Don't treat a same-page nav as a new page load. | 636 // Don't treat a same-page nav as a new page load. |
| 588 if (navigation_handle->IsSamePage()) | 637 if (navigation_handle->IsSamePage()) |
| 589 return; | 638 return; |
| 590 | 639 |
| 591 // Notify other loads that they may have been aborted by this committed load. | 640 // Notify other loads that they may have been aborted by this committed load. |
| 592 // Note that by using the committed navigation start as the abort cause, we | 641 // Note that by using the committed navigation start as the abort cause, we |
| 593 // lose data on provisional loads that were aborted by other provisional | 642 // lose data on provisional loads that were aborted by other provisional |
| 594 // loads. Those will either be listed as ABORT_OTHER or as being aborted by | 643 // loads. Those will either be listed as ABORT_OTHER or as being aborted by |
| 595 // this load. | 644 // this load. |
| 596 NotifyAbortAllLoadsWithTimestamp( | 645 NotifyAbortAllLoadsWithTimestamp( |
| 597 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), | 646 AbortTypeForPageTransition(navigation_handle->GetPageTransition()), |
| 598 navigation_handle->NavigationStart()); | 647 navigation_handle->NavigationStart(), false); |
| 599 | 648 |
| 600 committed_load_ = std::move(finished_nav); | 649 committed_load_ = std::move(finished_nav); |
| 601 aborted_provisional_loads_.clear(); | 650 aborted_provisional_loads_.clear(); |
| 602 | 651 |
| 603 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | 652 const GURL& browser_url = web_contents()->GetLastCommittedURL(); |
| 604 const std::string& mime_type = web_contents()->GetContentsMimeType(); | 653 const std::string& mime_type = web_contents()->GetContentsMimeType(); |
| 605 DCHECK(!browser_url.is_empty()); | 654 DCHECK(!browser_url.is_empty()); |
| 606 DCHECK(!mime_type.empty()); | 655 DCHECK(!mime_type.empty()); |
| 607 committed_load_->set_renderer_tracked( | 656 committed_load_->set_renderer_tracked( |
| 608 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); | 657 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 } | 710 } |
| 662 | 711 |
| 663 // If this is a crash, eagerly log the aborted provisional loads and the | 712 // If this is a crash, eagerly log the aborted provisional loads and the |
| 664 // committed load. |provisional_loads_| don't need to be destroyed here | 713 // committed load. |provisional_loads_| don't need to be destroyed here |
| 665 // because their lifetime is tied to the NavigationHandle. | 714 // because their lifetime is tied to the NavigationHandle. |
| 666 committed_load_.reset(); | 715 committed_load_.reset(); |
| 667 aborted_provisional_loads_.clear(); | 716 aborted_provisional_loads_.clear(); |
| 668 } | 717 } |
| 669 | 718 |
| 670 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { | 719 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) { |
| 671 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now()); | 720 NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true); |
| 672 } | 721 } |
| 673 | 722 |
| 674 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( | 723 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp( |
| 675 UserAbortType abort_type, | 724 UserAbortType abort_type, |
| 676 base::TimeTicks timestamp) { | 725 base::TimeTicks timestamp, |
| 726 bool is_browser_timetick) { | |
| 677 if (committed_load_) | 727 if (committed_load_) |
| 678 committed_load_->NotifyAbort(abort_type, timestamp); | 728 committed_load_->NotifyAbort(abort_type, timestamp, is_browser_timetick); |
| 679 for (const auto& kv : provisional_loads_) { | 729 for (const auto& kv : provisional_loads_) { |
| 680 kv.second->NotifyAbort(abort_type, timestamp); | 730 kv.second->NotifyAbort(abort_type, timestamp, is_browser_timetick); |
| 681 } | 731 } |
| 682 for (const auto& tracker : aborted_provisional_loads_) { | 732 for (const auto& tracker : aborted_provisional_loads_) { |
| 683 if (tracker->IsLikelyProvisionalAbort(timestamp)) | 733 if (tracker->IsLikelyProvisionalAbort(timestamp)) |
| 684 tracker->UpdateAbort(abort_type, timestamp); | 734 tracker->UpdateAbort(abort_type, timestamp, is_browser_timetick); |
| 685 } | 735 } |
| 686 aborted_provisional_loads_.clear(); | 736 aborted_provisional_loads_.clear(); |
| 687 } | 737 } |
| 688 | 738 |
| 689 std::unique_ptr<PageLoadTracker> | 739 std::unique_ptr<PageLoadTracker> |
| 690 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( | 740 MetricsWebContentsObserver::NotifyAbortedProvisionalLoadsNewNavigation( |
| 691 content::NavigationHandle* new_navigation) { | 741 content::NavigationHandle* new_navigation) { |
| 692 // If there are multiple aborted loads that can be attributed to this one, | 742 // If there are multiple aborted loads that can be attributed to this one, |
| 693 // just count the latest one for simplicity. Other loads will fall into the | 743 // just count the latest one for simplicity. Other loads will fall into the |
| 694 // OTHER bucket, though there shouldn't be very many. | 744 // OTHER bucket, though there shouldn't be very many. |
| 695 if (aborted_provisional_loads_.size() == 0) | 745 if (aborted_provisional_loads_.size() == 0) |
| 696 return nullptr; | 746 return nullptr; |
| 697 if (aborted_provisional_loads_.size() > 1) | 747 if (aborted_provisional_loads_.size() > 1) |
| 698 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); | 748 RecordInternalError(ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS); |
| 699 | 749 |
| 700 std::unique_ptr<PageLoadTracker> last_aborted_load = | 750 std::unique_ptr<PageLoadTracker> last_aborted_load = |
| 701 std::move(aborted_provisional_loads_.back()); | 751 std::move(aborted_provisional_loads_.back()); |
| 702 aborted_provisional_loads_.pop_back(); | 752 aborted_provisional_loads_.pop_back(); |
| 703 | 753 |
| 704 base::TimeTicks timestamp = new_navigation->NavigationStart(); | 754 base::TimeTicks timestamp = new_navigation->NavigationStart(); |
| 705 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) | 755 if (last_aborted_load->IsLikelyProvisionalAbort(timestamp)) |
| 706 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp); | 756 last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false); |
| 707 | 757 |
| 708 aborted_provisional_loads_.clear(); | 758 aborted_provisional_loads_.clear(); |
| 709 return last_aborted_load; | 759 return last_aborted_load; |
| 710 } | 760 } |
| 711 | 761 |
| 712 void MetricsWebContentsObserver::OnTimingUpdated( | 762 void MetricsWebContentsObserver::OnTimingUpdated( |
| 713 content::RenderFrameHost* render_frame_host, | 763 content::RenderFrameHost* render_frame_host, |
| 714 const PageLoadTiming& timing, | 764 const PageLoadTiming& timing, |
| 715 const PageLoadMetadata& metadata) { | 765 const PageLoadMetadata& metadata) { |
| 716 bool error = false; | 766 bool error = false; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 739 | 789 |
| 740 if (!committed_load_->UpdateTiming(timing, metadata)) { | 790 if (!committed_load_->UpdateTiming(timing, metadata)) { |
| 741 // If the page load tracker cannot update its timing, something is wrong | 791 // If the page load tracker cannot update its timing, something is wrong |
| 742 // with the IPC (it's from another load, or it's invalid in some other way). | 792 // with the IPC (it's from another load, or it's invalid in some other way). |
| 743 // We expect this to be a rare occurrence. | 793 // We expect this to be a rare occurrence. |
| 744 RecordInternalError(ERR_BAD_TIMING_IPC); | 794 RecordInternalError(ERR_BAD_TIMING_IPC); |
| 745 } | 795 } |
| 746 } | 796 } |
| 747 | 797 |
| 748 } // namespace page_load_metrics | 798 } // namespace page_load_metrics |
| OLD | NEW |