| 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> |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) { | 248 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) { |
| 249 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground, | 249 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground, |
| 250 completed_after_background); | 250 completed_after_background); |
| 251 } | 251 } |
| 252 | 252 |
| 253 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, | 253 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, |
| 254 const PageLoadTiming& last_timing, | 254 const PageLoadTiming& last_timing, |
| 255 const PageLoadTiming& new_timing, | 255 const PageLoadTiming& new_timing, |
| 256 const PageLoadMetadata& last_metadata, | 256 const PageLoadMetadata& last_metadata, |
| 257 const PageLoadExtraInfo& extra_info) { | 257 const PageLoadExtraInfo& extra_info) { |
| 258 if (extra_info.metadata.behavior_flags != last_metadata.behavior_flags) | 258 if (extra_info.main_frame_metadata.behavior_flags != |
| 259 last_metadata.behavior_flags) |
| 259 observer->OnLoadingBehaviorObserved(extra_info); | 260 observer->OnLoadingBehaviorObserved(extra_info); |
| 260 if (last_timing != new_timing) | 261 if (last_timing != new_timing) |
| 261 observer->OnTimingUpdate(new_timing, extra_info); | 262 observer->OnTimingUpdate(new_timing, extra_info); |
| 262 if (new_timing.dom_content_loaded_event_start && | 263 if (new_timing.dom_content_loaded_event_start && |
| 263 !last_timing.dom_content_loaded_event_start) | 264 !last_timing.dom_content_loaded_event_start) |
| 264 observer->OnDomContentLoadedEventStart(new_timing, extra_info); | 265 observer->OnDomContentLoadedEventStart(new_timing, extra_info); |
| 265 if (new_timing.load_event_start && !last_timing.load_event_start) | 266 if (new_timing.load_event_start && !last_timing.load_event_start) |
| 266 observer->OnLoadEventStart(new_timing, extra_info); | 267 observer->OnLoadEventStart(new_timing, extra_info); |
| 267 if (new_timing.first_layout && !last_timing.first_layout) | 268 if (new_timing.first_layout && !last_timing.first_layout) |
| 268 observer->OnFirstLayout(new_timing, extra_info); | 269 observer->OnFirstLayout(new_timing, extra_info); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 if (destination.navigation_start() > first_paint_time) | 500 if (destination.navigation_start() > first_paint_time) |
| 500 first_paint_to_navigation = | 501 first_paint_to_navigation = |
| 501 destination.navigation_start() - first_paint_time; | 502 destination.navigation_start() - first_paint_time; |
| 502 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, | 503 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, |
| 503 first_paint_to_navigation); | 504 first_paint_to_navigation); |
| 504 } else { | 505 } else { |
| 505 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); | 506 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); |
| 506 } | 507 } |
| 507 } | 508 } |
| 508 | 509 |
| 510 void PageLoadTracker::UpdateChildFrameMetadata( |
| 511 const PageLoadMetadata& child_metadata) { |
| 512 // Merge the child loading behavior flags with any we've already observed, |
| 513 // possibly from other child frames. |
| 514 const int last_child_loading_behavior_flags = |
| 515 child_frame_metadata_.behavior_flags; |
| 516 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags; |
| 517 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags) |
| 518 return; |
| 519 |
| 520 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo()); |
| 521 for (const auto& observer : observers_) { |
| 522 observer->OnLoadingBehaviorObserved(extra_info); |
| 523 } |
| 524 } |
| 525 |
| 509 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, | 526 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, |
| 510 const PageLoadMetadata& new_metadata) { | 527 const PageLoadMetadata& new_metadata) { |
| 511 // Throw away IPCs that are not relevant to the current navigation. | 528 // Throw away IPCs that are not relevant to the current navigation. |
| 512 // Two timing structures cannot refer to the same navigation if they indicate | 529 // Two timing structures cannot refer to the same navigation if they indicate |
| 513 // that a navigation started at different times, so a new timing struct with a | 530 // that a navigation started at different times, so a new timing struct with a |
| 514 // different start time from an earlier struct is considered invalid. | 531 // different start time from an earlier struct is considered invalid. |
| 515 bool valid_timing_descendent = | 532 bool valid_timing_descendent = |
| 516 timing_.navigation_start.is_null() || | 533 timing_.navigation_start.is_null() || |
| 517 timing_.navigation_start == new_timing.navigation_start; | 534 timing_.navigation_start == new_timing.navigation_start; |
| 518 // Ensure flags sent previously are still present in the new metadata fields. | 535 // Ensure flags sent previously are still present in the new metadata fields. |
| 519 bool valid_behavior_descendent = | 536 bool valid_behavior_descendent = |
| 520 (metadata_.behavior_flags & new_metadata.behavior_flags) == | 537 (main_frame_metadata_.behavior_flags & new_metadata.behavior_flags) == |
| 521 metadata_.behavior_flags; | 538 main_frame_metadata_.behavior_flags; |
| 522 if (IsValidPageLoadTiming(new_timing) && valid_timing_descendent && | 539 if (IsValidPageLoadTiming(new_timing) && valid_timing_descendent && |
| 523 valid_behavior_descendent) { | 540 valid_behavior_descendent) { |
| 524 DCHECK(did_commit_); // OnCommit() must be called first. | 541 DCHECK(did_commit_); // OnCommit() must be called first. |
| 525 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() | 542 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() |
| 526 // must be called before DispatchObserverTimingCallbacks, but its | 543 // must be called before DispatchObserverTimingCallbacks, but its |
| 527 // implementation depends on the state of metadata_, so we need to update | 544 // implementation depends on the state of main_frame_metadata_, so we need |
| 528 // metadata_ before calling GetPageLoadMetricsInfo. Thus, we make a copy of | 545 // to update main_frame_metadata_ before calling GetPageLoadMetricsInfo. |
| 529 // timing here, update timing_ and metadata_, and then proceed to dispatch | 546 // Thus, we make a copy of timing here, update timing_ and |
| 530 // the observer timing callbacks. | 547 // main_frame_metadata_, and then proceed to dispatch the observer timing |
| 548 // callbacks. |
| 531 const PageLoadTiming last_timing = timing_; | 549 const PageLoadTiming last_timing = timing_; |
| 532 timing_ = new_timing; | 550 timing_ = new_timing; |
| 533 | 551 |
| 534 const PageLoadMetadata last_metadata = metadata_; | 552 const PageLoadMetadata last_metadata = main_frame_metadata_; |
| 535 metadata_ = new_metadata; | 553 main_frame_metadata_ = new_metadata; |
| 536 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); | 554 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); |
| 537 for (const auto& observer : observers_) { | 555 for (const auto& observer : observers_) { |
| 538 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, | 556 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, |
| 539 last_metadata, info); | 557 last_metadata, info); |
| 540 } | 558 } |
| 541 return true; | 559 return true; |
| 542 } | 560 } |
| 543 return false; | 561 return false; |
| 544 } | 562 } |
| 545 | 563 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 } else { | 626 } else { |
| 609 DCHECK(page_end_time_.is_null()); | 627 DCHECK(page_end_time_.is_null()); |
| 610 } | 628 } |
| 611 | 629 |
| 612 // page_end_reason_ == END_NONE implies page_end_user_initiated_info_ is not | 630 // page_end_reason_ == END_NONE implies page_end_user_initiated_info_ is not |
| 613 // user initiated. | 631 // user initiated. |
| 614 DCHECK(page_end_reason_ != END_NONE || | 632 DCHECK(page_end_reason_ != END_NONE || |
| 615 (!page_end_user_initiated_info_.browser_initiated && | 633 (!page_end_user_initiated_info_.browser_initiated && |
| 616 !page_end_user_initiated_info_.user_gesture && | 634 !page_end_user_initiated_info_.user_gesture && |
| 617 !page_end_user_initiated_info_.user_input_event)); | 635 !page_end_user_initiated_info_.user_input_event)); |
| 618 return PageLoadExtraInfo(navigation_start_, first_background_time, | 636 return PageLoadExtraInfo( |
| 619 first_foreground_time, started_in_foreground_, | 637 navigation_start_, first_background_time, first_foreground_time, |
| 620 user_initiated_info_, url(), start_url_, did_commit_, | 638 started_in_foreground_, user_initiated_info_, url(), start_url_, |
| 621 page_end_reason_, page_end_user_initiated_info_, | 639 did_commit_, page_end_reason_, page_end_user_initiated_info_, |
| 622 page_end_time, metadata_); | 640 page_end_time, main_frame_metadata_, child_frame_metadata_); |
| 623 } | 641 } |
| 624 | 642 |
| 625 bool PageLoadTracker::HasMatchingNavigationRequestID( | 643 bool PageLoadTracker::HasMatchingNavigationRequestID( |
| 626 const content::GlobalRequestID& request_id) const { | 644 const content::GlobalRequestID& request_id) const { |
| 627 DCHECK(request_id != content::GlobalRequestID()); | 645 DCHECK(request_id != content::GlobalRequestID()); |
| 628 return navigation_request_id_.has_value() && | 646 return navigation_request_id_.has_value() && |
| 629 navigation_request_id_.value() == request_id; | 647 navigation_request_id_.value() == request_id; |
| 630 } | 648 } |
| 631 | 649 |
| 632 void PageLoadTracker::NotifyPageEnd(PageEndReason page_end_reason, | 650 void PageLoadTracker::NotifyPageEnd(PageEndReason page_end_reason, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 // user initiated. | 726 // user initiated. |
| 709 if (page_end_reason != END_CLIENT_REDIRECT) | 727 if (page_end_reason != END_CLIENT_REDIRECT) |
| 710 page_end_user_initiated_info_ = user_initiated_info; | 728 page_end_user_initiated_info_ = user_initiated_info; |
| 711 | 729 |
| 712 if (is_certainly_browser_timestamp) { | 730 if (is_certainly_browser_timestamp) { |
| 713 ClampBrowserTimestampIfInterProcessTimeTickSkew(&page_end_time_); | 731 ClampBrowserTimestampIfInterProcessTimeTickSkew(&page_end_time_); |
| 714 } | 732 } |
| 715 } | 733 } |
| 716 | 734 |
| 717 } // namespace page_load_metrics | 735 } // namespace page_load_metrics |
| OLD | NEW |