Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/page_load_tracker.h" | 5 #include "chrome/browser/page_load_metrics/page_load_tracker.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> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h" | 15 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h" |
| 16 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" | 16 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" |
| 17 #include "chrome/browser/prerender/prerender_contents.h" | 17 #include "chrome/browser/prerender/prerender_contents.h" |
| 18 #include "chrome/common/page_load_metrics/page_load_timing.h" | 18 #include "chrome/common/page_load_metrics/page_load_timing.h" |
| 19 #include "content/public/browser/navigation_details.h" | 19 #include "content/public/browser/navigation_details.h" |
| 20 #include "content/public/browser/navigation_handle.h" | 20 #include "content/public/browser/navigation_handle.h" |
| 21 #include "content/public/browser/render_frame_host.h" | |
| 21 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
| 22 #include "content/public/browser/web_contents_observer.h" | 23 #include "content/public/browser/web_contents_observer.h" |
| 23 #include "content/public/common/browser_side_navigation_policy.h" | 24 #include "content/public/common/browser_side_navigation_policy.h" |
| 24 #include "ui/base/page_transition_types.h" | 25 #include "ui/base/page_transition_types.h" |
| 25 | 26 |
| 26 // This macro invokes the specified method on each observer, passing the | 27 // This macro invokes the specified method on each observer, passing the |
| 27 // variable length arguments as the method's arguments, and removes the observer | 28 // variable length arguments as the method's arguments, and removes the observer |
| 28 // from the list of observers if the given method returns STOP_OBSERVING. | 29 // from the list of observers if the given method returns STOP_OBSERVING. |
| 29 #define INVOKE_AND_PRUNE_OBSERVERS(observers, Method, ...) \ | 30 #define INVOKE_AND_PRUNE_OBSERVERS(observers, Method, ...) \ |
| 30 for (auto it = observers.begin(); it != observers.end();) { \ | 31 for (auto it = observers.begin(); it != observers.end();) { \ |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 navigation_handle->GetWebContents()->GetContentsMimeType()); | 505 navigation_handle->GetWebContents()->GetContentsMimeType()); |
| 505 | 506 |
| 506 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); | 507 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); |
| 507 LogAbortChainHistograms(navigation_handle); | 508 LogAbortChainHistograms(navigation_handle); |
| 508 } | 509 } |
| 509 | 510 |
| 510 void PageLoadTracker::DidFinishSubFrameNavigation( | 511 void PageLoadTracker::DidFinishSubFrameNavigation( |
| 511 content::NavigationHandle* navigation_handle) { | 512 content::NavigationHandle* navigation_handle) { |
| 512 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnDidFinishSubFrameNavigation, | 513 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnDidFinishSubFrameNavigation, |
| 513 navigation_handle); | 514 navigation_handle); |
| 515 | |
| 516 // todo we don't want to erase if it's an aborted load (prev doc remains | |
| 517 // committed in that case) | |
| 518 child_frame_navigation_start_.erase(navigation_handle->GetFrameTreeNodeId()); | |
| 519 if (navigation_handle->HasCommitted() && | |
|
jkarlin
2017/05/05 19:19:25
Note that error pages count as commits.
Bryan McQuade
2017/05/07 19:32:11
good catch, thanks!. I decided that for tracking t
| |
| 520 !navigation_handle->IsSameDocument()) { | |
| 521 DCHECK_GE(navigation_handle->NavigationStart(), navigation_start_); | |
| 522 base::TimeDelta navigation_delta = | |
| 523 navigation_handle->NavigationStart() - navigation_start_; | |
| 524 child_frame_navigation_start_.insert(std::make_pair( | |
| 525 navigation_handle->GetFrameTreeNodeId(), navigation_delta)); | |
| 526 } | |
| 514 } | 527 } |
| 515 | 528 |
| 516 void PageLoadTracker::FailedProvisionalLoad( | 529 void PageLoadTracker::FailedProvisionalLoad( |
| 517 content::NavigationHandle* navigation_handle, | 530 content::NavigationHandle* navigation_handle, |
| 518 base::TimeTicks failed_load_time) { | 531 base::TimeTicks failed_load_time) { |
| 519 DCHECK(!failed_provisional_load_info_); | 532 DCHECK(!failed_provisional_load_info_); |
| 520 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( | 533 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( |
| 521 failed_load_time - navigation_handle->NavigationStart(), | 534 failed_load_time - navigation_handle->NavigationStart(), |
| 522 navigation_handle->GetNetErrorCode())); | 535 navigation_handle->GetNetErrorCode())); |
| 523 } | 536 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 554 if (destination.navigation_start() > first_paint_time) | 567 if (destination.navigation_start() > first_paint_time) |
| 555 first_paint_to_navigation = | 568 first_paint_to_navigation = |
| 556 destination.navigation_start() - first_paint_time; | 569 destination.navigation_start() - first_paint_time; |
| 557 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, | 570 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, |
| 558 first_paint_to_navigation); | 571 first_paint_to_navigation); |
| 559 } else { | 572 } else { |
| 560 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); | 573 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); |
| 561 } | 574 } |
| 562 } | 575 } |
| 563 | 576 |
| 564 void PageLoadTracker::UpdateChildFrameMetadata( | 577 void PageLoadTracker::UpdateSubFrameTiming( |
| 578 content::RenderFrameHost* render_frame_host, | |
| 579 const PageLoadTiming& new_timing, | |
| 580 const PageLoadMetadata& new_metadata) { | |
| 581 UpdateSubFrameMetadata(new_metadata); | |
| 582 const auto it = child_frame_navigation_start_.find( | |
| 583 render_frame_host->GetFrameTreeNodeId()); | |
| 584 if (it == child_frame_navigation_start_.end()) { | |
| 585 // note that this can happen if a navigation starts but aborts and then the | |
| 586 // frame contents is updated via e.g. document.open/document.write from its | |
| 587 // parent. we probably want this to pass through to observers, but it's | |
|
jkarlin
2017/05/05 19:19:25
This can also happen if a navigation aborts and fa
Bryan McQuade
2017/05/07 19:32:10
Yes - I fixed our tracking of loads in DidFinishSu
| |
| 588 // unclear what we should use for a nav start value (what is the nav start | |
| 589 // value in the render process? maybe we should be sending the nav start | |
| 590 // timeticks from the renderer?) | |
| 591 // todo log an error here to keep track of frequency of this case | |
| 592 return; | |
| 593 } | |
| 594 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); | |
| 595 for (const auto& observer : observers_) { | |
| 596 observer->OnSubFrameTimingUpdate(render_frame_host->GetFrameTreeNodeId(), | |
| 597 it->second, new_timing, new_metadata, | |
| 598 info); | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 void PageLoadTracker::UpdateSubFrameMetadata( | |
| 565 const PageLoadMetadata& child_metadata) { | 603 const PageLoadMetadata& child_metadata) { |
| 566 // Merge the child loading behavior flags with any we've already observed, | 604 // Merge the child loading behavior flags with any we've already observed, |
| 567 // possibly from other child frames. | 605 // possibly from other child frames. |
| 568 const int last_child_loading_behavior_flags = | 606 const int last_child_loading_behavior_flags = |
| 569 child_frame_metadata_.behavior_flags; | 607 child_frame_metadata_.behavior_flags; |
| 570 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags; | 608 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags; |
| 571 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags) | 609 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags) |
| 572 return; | 610 return; |
| 573 | 611 |
| 574 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo()); | 612 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo()); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 observer->MediaStartedPlaying(video_type, is_in_main_frame); | 850 observer->MediaStartedPlaying(video_type, is_in_main_frame); |
| 813 } | 851 } |
| 814 | 852 |
| 815 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay, | 853 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay, |
| 816 base::TimeDelta actual_delay) { | 854 base::TimeDelta actual_delay) { |
| 817 for (const auto& observer : observers_) | 855 for (const auto& observer : observers_) |
| 818 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay); | 856 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay); |
| 819 } | 857 } |
| 820 | 858 |
| 821 } // namespace page_load_metrics | 859 } // namespace page_load_metrics |
| OLD | NEW |