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::UpdateChildMetadata( |
| 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 |