Index: chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h |
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7af687e3be8e5b039915ab0d0ca683b208e66fc6 |
--- /dev/null |
+++ b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h |
@@ -0,0 +1,162 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_H_ |
+#define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_H_ |
+ |
+#include <map> |
+ |
+#include "base/time/time.h" |
+#include "chrome/common/page_load_metrics/page_load_metrics.mojom.h" |
+ |
+namespace content { |
+class NavigationHandle; |
+class RenderFrameHost; |
+} // namespace content |
+ |
+namespace page_load_metrics { |
+ |
+class PageLoadMetricsEmbedderInterface; |
+ |
+namespace internal { |
+ |
+// Used to track the status of PageLoadTimings received from the render process. |
+// |
+// If you add elements to this enum, make sure you update the enum value in |
+// histograms.xml. Only add elements to the end to prevent inconsistencies |
+// between versions. |
+enum PageLoadTimingStatus { |
+ // The PageLoadTiming is valid (all data within the PageLoadTiming is |
+ // consistent with expectations). |
+ VALID, |
+ |
+ // All remaining status codes are for invalid PageLoadTimings. |
+ |
+ // The PageLoadTiming was empty. |
+ INVALID_EMPTY_TIMING, |
+ |
+ // The PageLoadTiming had a null navigation_start. |
+ INVALID_NULL_NAVIGATION_START, |
+ |
+ // Script load or execution durations in the PageLoadTiming were too long. |
+ INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE, |
+ INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE, |
+ INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD, |
+ INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC, |
+ |
+ // The order of two events in the PageLoadTiming was invalid. Either the first |
+ // wasn't present when the second was present, or the second was reported as |
+ // happening before the first. |
+ INVALID_ORDER_RESPONSE_START_PARSE_START, |
+ INVALID_ORDER_PARSE_START_PARSE_STOP, |
+ INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED, |
+ INVALID_ORDER_DOM_CONTENT_LOADED_LOAD, |
+ INVALID_ORDER_PARSE_START_FIRST_LAYOUT, |
+ INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT, |
+ INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT, |
+ INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT, |
+ INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT, |
+ INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT, |
+ |
+ // New values should be added before this final entry. |
+ LAST_PAGE_LOAD_TIMING_STATUS |
+}; |
+ |
+extern const char kPageLoadTimingStatus[]; |
+ |
+} // namespace internal |
+ |
+// PageLoadMetricsUpdateDispatcher manages updates to page load metrics data, |
+// and dispatches them to the Client. PageLoadMetricsUpdateDispatcher may delay |
+// dispatching metrics updates to the Client in cases where metrics state hasn't |
+// stabilized. |
+class PageLoadMetricsUpdateDispatcher { |
+ public: |
+ // The Client class is updated when metrics managed by the dispatcher have |
+ // changed. Typically it owns the dispatcher. |
+ class Client { |
+ public: |
+ virtual ~Client() {} |
+ |
+ virtual void OnTimingChanged() = 0; |
+ virtual void OnMainFrameMetadataChanged() = 0; |
+ virtual void OnSubframeMetadataChanged() = 0; |
+ }; |
+ |
+ // The |client| instance must outlive this object. |
+ PageLoadMetricsUpdateDispatcher( |
+ Client* client, |
+ content::NavigationHandle* navigation_handle, |
+ PageLoadMetricsEmbedderInterface* embedder_interface); |
+ ~PageLoadMetricsUpdateDispatcher(); |
+ |
+ void UpdateMetrics(content::RenderFrameHost* render_frame_host, |
+ const mojom::PageLoadTiming& new_timing, |
+ const mojom::PageLoadMetadata& new_metadata); |
+ |
+ void DidFinishSubFrameNavigation( |
+ content::NavigationHandle* navigation_handle); |
+ |
+ const mojom::PageLoadTiming& timing() const { |
+ return *(current_merged_page_timing_.get()); |
+ } |
+ |
+ const mojom::PageLoadMetadata& main_frame_metadata() const { |
+ return *(main_frame_metadata_.get()); |
+ } |
+ const mojom::PageLoadMetadata& subframe_metadata() const { |
+ return *(subframe_metadata_.get()); |
+ } |
+ |
+ private: |
+ using FrameTreeNodeId = int; |
+ |
+ void UpdateMainFrameTiming(const mojom::PageLoadTiming& new_timing); |
+ void UpdateSubFrameTiming(content::RenderFrameHost* render_frame_host, |
+ const mojom::PageLoadTiming& new_timing); |
+ |
+ void UpdateMainFrameMetadata(const mojom::PageLoadMetadata& new_metadata); |
+ void UpdateSubFrameMetadata(const mojom::PageLoadMetadata& subframe_metadata); |
+ |
+ // Merge values from |new_paint_timing| into |pending_merged_page_timing_|, |
+ // offsetting any new timings by the |navigation_start_offset|. |
+ void MergePaintTiming(base::TimeDelta navigation_start_offset, |
+ const mojom::PaintTiming& new_paint_timing, |
+ bool is_main_frame); |
+ |
+ void DispatchTimingUpdates(); |
+ |
+ // The client is guaranteed to outlive this object. |
+ Client* const client_; |
+ |
+ // Interface to chrome features. Must outlive the class. |
+ PageLoadMetricsEmbedderInterface* const embedder_interface_; |
+ |
+ // Time the navigation for this page load was initiated. |
+ const base::TimeTicks navigation_start_; |
+ |
+ // PageLoadTiming for the currently tracked page. The fields in |paint_timing| |
+ // are merged across all frames in the document. All other fields are from the |
+ // main frame document. current_merged_page_timing_ contains the most recent |
Charlie Harrison
2017/05/24 21:02:51
|current_merged_page_timing_| and elsewhere in thi
Bryan McQuade
2017/05/25 02:30:21
done
|
+ // valid page load timing data, while pending_merged_page_timing_ contains |
+ // pending updates received since current_merged_page_timing_ was last |
+ // updated. pending_merged_page_timing_ will be copied to |
Charlie Harrison
2017/05/24 21:02:52
"updated to the client" maybe? There are multiple
Bryan McQuade
2017/05/25 02:30:21
used 'dispatched to the client'
|
+ // current_merged_page_timing_ once it is valid, at the time the |
+ // Client::OnTimingChanged callback is invoked. |
+ mojom::PageLoadTimingPtr current_merged_page_timing_; |
+ mojom::PageLoadTimingPtr pending_merged_page_timing_; |
+ |
+ mojom::PageLoadMetadataPtr main_frame_metadata_; |
+ mojom::PageLoadMetadataPtr subframe_metadata_; |
+ |
+ // Navigation start offsets for the most recently committed document in each |
+ // frame. |
+ std::map<FrameTreeNodeId, base::TimeDelta> subframe_navigation_start_offset_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsUpdateDispatcher); |
Charlie Harrison
2017/05/24 21:02:51
#include "base/macros.h"
Bryan McQuade
2017/05/25 02:30:21
done
|
+}; |
+ |
+} // namespace page_load_metrics |
+ |
+#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UPDATE_DISPATCHER_H_ |