OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_H_ |
| 6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_H_ |
| 7 |
| 8 #include <map> |
| 9 |
| 10 #include "base/macros.h" |
| 11 #include "base/time/time.h" |
| 12 #include "chrome/common/page_load_metrics/page_load_metrics.mojom.h" |
| 13 |
| 14 namespace content { |
| 15 class NavigationHandle; |
| 16 class RenderFrameHost; |
| 17 } // namespace content |
| 18 |
| 19 namespace page_load_metrics { |
| 20 |
| 21 class PageLoadMetricsEmbedderInterface; |
| 22 |
| 23 namespace internal { |
| 24 |
| 25 // Used to track the status of PageLoadTimings received from the render process. |
| 26 // |
| 27 // If you add elements to this enum, make sure you update the enum value in |
| 28 // histograms.xml. Only add elements to the end to prevent inconsistencies |
| 29 // between versions. |
| 30 enum PageLoadTimingStatus { |
| 31 // The PageLoadTiming is valid (all data within the PageLoadTiming is |
| 32 // consistent with expectations). |
| 33 VALID, |
| 34 |
| 35 // All remaining status codes are for invalid PageLoadTimings. |
| 36 |
| 37 // The PageLoadTiming was empty. |
| 38 INVALID_EMPTY_TIMING, |
| 39 |
| 40 // The PageLoadTiming had a null navigation_start. |
| 41 INVALID_NULL_NAVIGATION_START, |
| 42 |
| 43 // Script load or execution durations in the PageLoadTiming were too long. |
| 44 INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE, |
| 45 INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE, |
| 46 INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD, |
| 47 INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC, |
| 48 |
| 49 // The order of two events in the PageLoadTiming was invalid. Either the first |
| 50 // wasn't present when the second was present, or the second was reported as |
| 51 // happening before the first. |
| 52 INVALID_ORDER_RESPONSE_START_PARSE_START, |
| 53 INVALID_ORDER_PARSE_START_PARSE_STOP, |
| 54 INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED, |
| 55 INVALID_ORDER_DOM_CONTENT_LOADED_LOAD, |
| 56 INVALID_ORDER_PARSE_START_FIRST_LAYOUT, |
| 57 INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT, |
| 58 INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT, |
| 59 INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT, |
| 60 INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT, |
| 61 INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT, |
| 62 |
| 63 // New values should be added before this final entry. |
| 64 LAST_PAGE_LOAD_TIMING_STATUS |
| 65 }; |
| 66 |
| 67 extern const char kPageLoadTimingStatus[]; |
| 68 |
| 69 } // namespace internal |
| 70 |
| 71 // PageLoadMetricsUpdateDispatcher manages updates to page load metrics data, |
| 72 // and dispatches them to the Client. PageLoadMetricsUpdateDispatcher may delay |
| 73 // dispatching metrics updates to the Client in cases where metrics state hasn't |
| 74 // stabilized. |
| 75 class PageLoadMetricsUpdateDispatcher { |
| 76 public: |
| 77 // The Client class is updated when metrics managed by the dispatcher have |
| 78 // changed. Typically it owns the dispatcher. |
| 79 class Client { |
| 80 public: |
| 81 virtual ~Client() {} |
| 82 |
| 83 virtual void OnTimingChanged() = 0; |
| 84 virtual void OnMainFrameMetadataChanged() = 0; |
| 85 virtual void OnSubframeMetadataChanged() = 0; |
| 86 }; |
| 87 |
| 88 // The |client| instance must outlive this object. |
| 89 PageLoadMetricsUpdateDispatcher( |
| 90 Client* client, |
| 91 content::NavigationHandle* navigation_handle, |
| 92 PageLoadMetricsEmbedderInterface* embedder_interface); |
| 93 ~PageLoadMetricsUpdateDispatcher(); |
| 94 |
| 95 void UpdateMetrics(content::RenderFrameHost* render_frame_host, |
| 96 const mojom::PageLoadTiming& new_timing, |
| 97 const mojom::PageLoadMetadata& new_metadata); |
| 98 |
| 99 void DidFinishSubFrameNavigation( |
| 100 content::NavigationHandle* navigation_handle); |
| 101 |
| 102 const mojom::PageLoadTiming& timing() const { |
| 103 return *(current_merged_page_timing_.get()); |
| 104 } |
| 105 |
| 106 const mojom::PageLoadMetadata& main_frame_metadata() const { |
| 107 return *(main_frame_metadata_.get()); |
| 108 } |
| 109 const mojom::PageLoadMetadata& subframe_metadata() const { |
| 110 return *(subframe_metadata_.get()); |
| 111 } |
| 112 |
| 113 private: |
| 114 using FrameTreeNodeId = int; |
| 115 |
| 116 void UpdateMainFrameTiming(const mojom::PageLoadTiming& new_timing); |
| 117 void UpdateSubFrameTiming(content::RenderFrameHost* render_frame_host, |
| 118 const mojom::PageLoadTiming& new_timing); |
| 119 |
| 120 void UpdateMainFrameMetadata(const mojom::PageLoadMetadata& new_metadata); |
| 121 void UpdateSubFrameMetadata(const mojom::PageLoadMetadata& subframe_metadata); |
| 122 |
| 123 // Merge values from |new_paint_timing| into |pending_merged_page_timing_|, |
| 124 // offsetting any new timings by the |navigation_start_offset|. |
| 125 void MergePaintTiming(base::TimeDelta navigation_start_offset, |
| 126 const mojom::PaintTiming& new_paint_timing, |
| 127 bool is_main_frame); |
| 128 |
| 129 void DispatchTimingUpdates(); |
| 130 |
| 131 // The client is guaranteed to outlive this object. |
| 132 Client* const client_; |
| 133 |
| 134 // Interface to chrome features. Must outlive the class. |
| 135 PageLoadMetricsEmbedderInterface* const embedder_interface_; |
| 136 |
| 137 // Time the navigation for this page load was initiated. |
| 138 const base::TimeTicks navigation_start_; |
| 139 |
| 140 // PageLoadTiming for the currently tracked page. The fields in |paint_timing| |
| 141 // are merged across all frames in the document. All other fields are from the |
| 142 // main frame document. |current_merged_page_timing_| contains the most recent |
| 143 // valid page load timing data, while pending_merged_page_timing_ contains |
| 144 // pending updates received since |current_merged_page_timing_| was last |
| 145 // dispatched to the client. pending_merged_page_timing_ will be copied to |
| 146 // |current_merged_page_timing_| once it is valid, at the time the |
| 147 // Client::OnTimingChanged callback is invoked. |
| 148 mojom::PageLoadTimingPtr current_merged_page_timing_; |
| 149 mojom::PageLoadTimingPtr pending_merged_page_timing_; |
| 150 |
| 151 mojom::PageLoadMetadataPtr main_frame_metadata_; |
| 152 mojom::PageLoadMetadataPtr subframe_metadata_; |
| 153 |
| 154 // Navigation start offsets for the most recently committed document in each |
| 155 // frame. |
| 156 std::map<FrameTreeNodeId, base::TimeDelta> subframe_navigation_start_offset_; |
| 157 |
| 158 DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsUpdateDispatcher); |
| 159 }; |
| 160 |
| 161 } // namespace page_load_metrics |
| 162 |
| 163 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_
H_ |
OLD | NEW |