Chromium Code Reviews| 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_ |