1 // Copyright 2015 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 COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_
6 #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/macros.h"
12 #include "base/optional.h"
13 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
14 #include "components/page_load_metrics/browser/page_load_metrics_observer_delegate.h"
15 #include "components/page_load_metrics/common/page_load_timing.h"
16 #include "content/public/browser/navigation_handle.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/cookies/canonical_cookie.h"
21 #include "services/metrics/public/cpp/ukm_source.h"
22 #include "services/network/public/mojom/fetch_api.mojom.h"
23 #include "third_party/blink/public/common/input/web_input_event.h"
24 #include "url/gurl.h"
25 
26 namespace content {
27 class RenderFrameHost;
28 }  // namespace content
29 
30 namespace page_load_metrics {
31 
32 // Storage types reported to page load metrics observers on storage
33 // accesses.
34 enum class StorageType {
35   kLocalStorage,
36   kSessionStorage,
37   kFileSystem,
38   kIndexedDb,
39   kCacheStorage
40 };
41 
42 // Information related to failed provisional loads.
43 struct FailedProvisionalLoadInfo {
44   FailedProvisionalLoadInfo(base::TimeDelta interval, net::Error error);
45   ~FailedProvisionalLoadInfo();
46 
47   base::TimeDelta time_to_failed_provisional_load;
48   net::Error error;
49 };
50 
51 // Information related to whether an associated action, such as a navigation or
52 // an abort, was initiated by a user. Clicking a link or tapping on a UI
53 // element are examples of user initiation actions.
54 struct UserInitiatedInfo {
NotUserInitiatedUserInitiatedInfo55   static UserInitiatedInfo NotUserInitiated() {
56     return UserInitiatedInfo(false, false, false);
57   }
58 
BrowserInitiatedUserInitiatedInfo59   static UserInitiatedInfo BrowserInitiated() {
60     return UserInitiatedInfo(true, false, false);
61   }
62 
RenderInitiatedUserInitiatedInfo63   static UserInitiatedInfo RenderInitiated(bool user_gesture,
64                                            bool user_input_event) {
65     return UserInitiatedInfo(false, user_gesture, user_input_event);
66   }
67 
68   // Whether the associated action was initiated from the browser process, as
69   // opposed to from the render process. We generally assume that all actions
70   // initiated from the browser process are user initiated.
71   bool browser_initiated;
72 
73   // Whether the associated action was initiated by a user, according to user
74   // gesture tracking in content and Blink, as reported by NavigationHandle.
75   // This is based on the heuristic the popup blocker uses.
76   bool user_gesture;
77 
78   // Whether an input even directly led to the navigation, according to
79   // input start time tracking in the renderer, as reported by NavigationHandle.
80   // Note that this metric is still experimental and may not be fully
81   // implemented. All known issues are blocking crbug.com/889220. Currently
82   // all known gaps affect browser-side navigations.
83   bool user_input_event;
84 
85  private:
UserInitiatedInfoUserInitiatedInfo86   UserInitiatedInfo(bool browser_initiated,
87                     bool user_gesture,
88                     bool user_input_event)
89       : browser_initiated(browser_initiated),
90         user_gesture(user_gesture),
91         user_input_event(user_input_event) {}
92 };
93 
94 // Information about how the page rendered during the browsing session.
95 // Derived from the FrameRenderDataUpdate that is sent via UpdateTiming IPC.
96 struct PageRenderData {
97   PageRenderData() = default;
98 
99   // How much visible elements on the page shifted (bit.ly/lsm-explainer).
100   float layout_shift_score = 0;
101 
102   // How much visible elements on the page shifted (bit.ly/lsm-explainer),
103   // before user input or document scroll. This field's meaning is context-
104   // dependent (see comments on page_render_data_ and main_frame_render_data_
105   // in PageLoadMetricsUpdateDispatcher).
106   float layout_shift_score_before_input_or_scroll = 0;
107 
108   // How many LayoutBlock instances were created.
109   uint64_t all_layout_block_count = 0;
110 
111   // How many LayoutNG-based LayoutBlock instances were created.
112   uint64_t ng_layout_block_count = 0;
113 
114   // How many times LayoutObject::UpdateLayout() is called.
115   uint64_t all_layout_call_count = 0;
116 
117   // How many times LayoutNG-based LayoutObject::UpdateLayout() is called.
118   uint64_t ng_layout_call_count = 0;
119 };
120 
121 // Information related to layout shift normalization for different strategies.
122 struct NormalizedCLSData {
123   NormalizedCLSData() = default;
124 
125   // Maximum CLS of 300ms sliding windows.
126   double sliding_windows_duration300ms_max_cls = 0.0;
127 
128   // Maximum CLS of 1000ms sliding windows.
129   double sliding_windows_duration1000ms_max_cls = 0.0;
130 
131   // Maximum CLS of session windows. The gap between two consecutive shifts is
132   // not bigger than 1000ms and the maximum window size is 5000ms.
133   double session_windows_gap1000ms_max5000ms_max_cls = 0.0;
134 
135   // Maximum CLS of session windows. The gap between two consecutive shifts is
136   // not bigger than 1000ms.
137   double session_windows_gap1000ms_maxMax_max_cls = 0.0;
138 
139   // The average CLS of session windows. The gap between two consecutive shifts
140   // is not bigger than 5000ms.
141   double session_windows_gap5000ms_maxMax_average_cls = 0.0;
142 
143   // If true, will not report the data in UKM.
144   bool data_tainted = false;
145 };
146 
147 // Container for various information about a completed request within a page
148 // load.
149 struct ExtraRequestCompleteInfo {
150   ExtraRequestCompleteInfo(
151       const url::Origin& origin_of_final_url,
152       const net::IPEndPoint& remote_endpoint,
153       int frame_tree_node_id,
154       bool was_cached,
155       int64_t raw_body_bytes,
156       int64_t original_network_content_length,
157       std::unique_ptr<data_reduction_proxy::DataReductionProxyData>
158           data_reduction_proxy_data,
159       network::mojom::RequestDestination request_destination,
160       int net_error,
161       std::unique_ptr<net::LoadTimingInfo> load_timing_info);
162 
163   ExtraRequestCompleteInfo(const ExtraRequestCompleteInfo& other);
164 
165   ~ExtraRequestCompleteInfo();
166 
167   // The origin of the final URL for the request (final = after redirects).
168   //
169   // The full URL is not available, because in some cases the path and query
170   // be sanitized away - see https://crbug.com/973885.
171   const url::Origin origin_of_final_url;
172 
173   // The host (IP address) and port for the request.
174   const net::IPEndPoint remote_endpoint;
175 
176   // The frame tree node id that initiated the request.
177   const int frame_tree_node_id;
178 
179   // True if the resource was loaded from cache.
180   const bool was_cached;
181 
182   // The number of body (not header) prefilter bytes.
183   const int64_t raw_body_bytes;
184 
185   // The number of body (not header) bytes that the data reduction proxy saw
186   // before it compressed the requests.
187   const int64_t original_network_content_length;
188 
189   // Data related to data saver.
190   const std::unique_ptr<data_reduction_proxy::DataReductionProxyData>
191       data_reduction_proxy_data;
192 
193   // The type of the request as gleaned from the mime type.  This may
194   // be more accurate than the type in the ExtraRequestStartInfo since we can
195   // examine the type headers that arrived with the request.  During XHRs, we
196   // sometimes see resources come back as a different type than we expected.
197   const network::mojom::RequestDestination request_destination;
198 
199   // The network error encountered by the request, as defined by
200   // net/base/net_error_list.h. If no error was encountered, this value will be
201   // 0.
202   const int net_error;
203 
204   // Additional timing information.
205   const std::unique_ptr<net::LoadTimingInfo> load_timing_info;
206 };
207 
208 // Interface for PageLoadMetrics observers. All instances of this class are
209 // owned by the PageLoadTracker tracking a page load.
210 class PageLoadMetricsObserver {
211  public:
212   // ObservePolicy is used as a return value on some PageLoadMetricsObserver
213   // callbacks to indicate whether the observer would like to continue observing
214   // metric callbacks. Observers that wish to continue observing metric
215   // callbacks should return CONTINUE_OBSERVING; observers that wish to stop
216   // observing callbacks should return STOP_OBSERVING. Observers that return
217   // STOP_OBSERVING may be deleted.
218   enum ObservePolicy {
219     CONTINUE_OBSERVING,
220     STOP_OBSERVING,
221   };
222 
223   // These values are persisted to logs. Entries should not be renumbered and
224   // numeric values should never be reused.
225   enum class LargestContentState {
226     kReported = 0,
227     kLargestImageLoading = 1,
228     kNotFound = 2,
229     kFoundButNotReported = 3,
230     kMaxValue = kFoundButNotReported,
231   };
232 
233   using FrameTreeNodeId = int;
234 
~PageLoadMetricsObserver()235   virtual ~PageLoadMetricsObserver() {}
236 
237   static bool IsStandardWebPageMimeType(const std::string& mime_type);
238 
239   // Gets/Sets the delegate. The delegate must outlive the observer and is
240   // normally set when the observer is first registered for the page load. The
241   // delegate can only be set once.
242   const PageLoadMetricsObserverDelegate& GetDelegate() const;
243   void SetDelegate(PageLoadMetricsObserverDelegate*);
244 
245   // The page load started, with the given navigation handle.
246   // currently_committed_url contains the URL of the committed page load at the
247   // time the navigation for navigation_handle was initiated, or the empty URL
248   // if there was no committed page load at the time the navigation was
249   // initiated.
250   virtual ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
251                                 const GURL& currently_committed_url,
252                                 bool started_in_foreground);
253 
254   // OnRedirect is triggered when a page load redirects to another URL.
255   // The navigation handle holds relevant data for the navigation, but will
256   // be destroyed soon after this call. Don't hold a reference to it. This can
257   // be called multiple times.
258   virtual ObservePolicy OnRedirect(
259       content::NavigationHandle* navigation_handle);
260 
261   // OnCommit is triggered when a page load commits, i.e. when we receive the
262   // first data for the request. The navigation handle holds relevant data for
263   // the navigation, but will be destroyed soon after this call. Don't hold a
264   // reference to it.
265   // Observers that return STOP_OBSERVING will not receive any additional
266   // callbacks, and will be deleted after invocation of this method returns.
267   virtual ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
268                                  ukm::SourceId source_id);
269 
270   // OnDidInternalNavigationAbort is triggered when the main frame navigation
271   // aborts with HTTP responses that don't commit, such as HTTP 204 responses
272   // and downloads. Note that |navigation_handle| will be destroyed
273   // soon after this call. Don't hold a reference to it.
OnDidInternalNavigationAbort(content::NavigationHandle * navigation_handle)274   virtual void OnDidInternalNavigationAbort(
275       content::NavigationHandle* navigation_handle) {}
276 
277   // ReadyToCommitNextNavigation is triggered when a frame navigation is
278   // ready to commit, but has not yet been committed. This is only called by
279   // a PageLoadTracker for a committed load, meaning that this call signals we
280   // are ready to commit a navigation to a new page.
ReadyToCommitNextNavigation(content::NavigationHandle * navigation_handle)281   virtual void ReadyToCommitNextNavigation(
282       content::NavigationHandle* navigation_handle) {}
283 
284   // OnDidFinishSubFrameNavigation is triggered when a sub-frame of the
285   // committed page has finished navigating. It has either committed, aborted,
286   // was a same document navigation, or has been replaced. It is up to the
287   // observer to query |navigation_handle| to determine which happened. Note
288   // that |navigation_handle| will be destroyed soon after this call. Don't
289   // hold a reference to it.
OnDidFinishSubFrameNavigation(content::NavigationHandle * navigation_handle)290   virtual void OnDidFinishSubFrameNavigation(
291       content::NavigationHandle* navigation_handle) {}
292 
293   // OnCommitSameDocumentNavigation is triggered when a same-document navigation
294   // commits within the main frame of the current page. Note that
295   // |navigation_handle| will be destroyed soon after this call. Don't hold a
296   // reference to it.
OnCommitSameDocumentNavigation(content::NavigationHandle * navigation_handle)297   virtual void OnCommitSameDocumentNavigation(
298       content::NavigationHandle* navigation_handle) {}
299 
300   // OnHidden is triggered when a page leaves the foreground. It does not fire
301   // when a foreground page is permanently closed; for that, listen to
302   // OnComplete instead.
303   virtual ObservePolicy OnHidden(const mojom::PageLoadTiming& timing);
304 
305   // OnShown is triggered when a page is brought to the foreground. It does not
306   // fire when the page first loads; for that, listen for OnStart instead.
307   virtual ObservePolicy OnShown();
308 
309   // OnEnterBackForwardCache is triggered when a page is put into the
310   // back-forward cache. This page can be reused in the future for a
311   // back-forward navigation, in this case this OnRestoreFromBackForwardCache
312   // will be called for this PageLoadMetricsObserver. Note that the page in the
313   // back-forward cache can be evicted at any moment, and in this case
314   // OnComplete will be called.
315   //
316   // At the moment, the default implementtion of OnEnterBackForwardCache()
317   // invokes OnComplete and returns STOP_OBSERVING, so the page will not be
318   // tracked after it is stored in the back-forward cache and after it is
319   // restored. Return CONTINUE_OBSERVING explicitly to ensure that you cover the
320   // entire lifetime of the page, which is important for cases like tracking
321   // feature use counts or total network usage.
322   //
323   // TODO(hajimehoshi): Consider to remove |timing| argument by adding a
324   // function to PageLoadMetricsObserverDelegate. This would require
325   // investigation to determine exposing the timing from the delegate would be
326   // really safe.
327   virtual ObservePolicy OnEnterBackForwardCache(
328       const mojom::PageLoadTiming& timing);
329 
330   // OnRestoreFromBackForwardCache is triggered when a page is restored from
331   // the back-forward cache.
OnRestoreFromBackForwardCache(const mojom::PageLoadTiming & timing,content::NavigationHandle * navigation_handle)332   virtual void OnRestoreFromBackForwardCache(
333       const mojom::PageLoadTiming& timing,
334       content::NavigationHandle* navigation_handle) {}
335 
336   // Called before OnCommit. The observer should return whether it wishes to
337   // observe navigations whose main resource has MIME type |mine_type|. The
338   // default is to observe HTML and XHTML only. Note that PageLoadTrackers only
339   // track XHTML, HTML, and MHTML (related/multipart).
340   virtual ObservePolicy ShouldObserveMimeType(
341       const std::string& mime_type) const;
342 
343   // The callbacks below are only invoked after a navigation commits, for
344   // tracked page loads. Page loads that don't meet the criteria for being
345   // tracked at the time a navigation commits will not receive any of the
346   // callbacks below.
347 
348   // OnTimingUpdate is triggered when an updated PageLoadTiming is available at
349   // the page (page is essentially main frame, with merged values across all
350   // frames for some paint timing values) or subframe level. This method may be
351   // called multiple times over the course of the page load. This method is
352   // currently only intended for use in testing. Most implementers should
353   // implement one of the On* callbacks, such as OnFirstContentfulPaint or
354   // OnDomContentLoadedEventStart. Please email loading-dev@chromium.org if you
355   // intend to override this method.
356   //
357   // If |subframe_rfh| is nullptr, the update took place in the main frame.
OnTimingUpdate(content::RenderFrameHost * subframe_rfh,const mojom::PageLoadTiming & timing)358   virtual void OnTimingUpdate(content::RenderFrameHost* subframe_rfh,
359                               const mojom::PageLoadTiming& timing) {}
360 
361   // OnRenderDataUpdate is triggered when an updated PageRenderData is available
362   // at the subframe level. This method may be called multiple times over the
363   // course of the page load.
OnSubFrameRenderDataUpdate(content::RenderFrameHost * subframe_rfh,const mojom::FrameRenderDataUpdate & render_data)364   virtual void OnSubFrameRenderDataUpdate(
365       content::RenderFrameHost* subframe_rfh,
366       const mojom::FrameRenderDataUpdate& render_data) {}
367 
368   // Triggered when an updated CpuTiming is available at the page or subframe
369   // level. This method is intended for monitoring cpu usage and load across
370   // the frames on a page during navigation.
OnCpuTimingUpdate(content::RenderFrameHost * subframe_rfh,const mojom::CpuTiming & timing)371   virtual void OnCpuTimingUpdate(content::RenderFrameHost* subframe_rfh,
372                                  const mojom::CpuTiming& timing) {}
373 
374   // OnUserInput is triggered when a new user input is passed in to
375   // web_contents.
OnUserInput(const blink::WebInputEvent & event,const mojom::PageLoadTiming & timing)376   virtual void OnUserInput(const blink::WebInputEvent& event,
377                            const mojom::PageLoadTiming& timing) {}
378 
379   // The following methods are invoked at most once, when the timing for the
380   // associated event first becomes available.
OnDomContentLoadedEventStart(const mojom::PageLoadTiming & timing)381   virtual void OnDomContentLoadedEventStart(
382       const mojom::PageLoadTiming& timing) {}
OnLoadEventStart(const mojom::PageLoadTiming & timing)383   virtual void OnLoadEventStart(const mojom::PageLoadTiming& timing) {}
OnFirstLayout(const mojom::PageLoadTiming & timing)384   virtual void OnFirstLayout(const mojom::PageLoadTiming& timing) {}
OnParseStart(const mojom::PageLoadTiming & timing)385   virtual void OnParseStart(const mojom::PageLoadTiming& timing) {}
OnParseStop(const mojom::PageLoadTiming & timing)386   virtual void OnParseStop(const mojom::PageLoadTiming& timing) {}
387 
388   // On*PaintInPage(...) are invoked when the first relevant paint in the page,
389   // across all frames, is observed.
OnFirstPaintInPage(const mojom::PageLoadTiming & timing)390   virtual void OnFirstPaintInPage(const mojom::PageLoadTiming& timing) {}
OnFirstImagePaintInPage(const mojom::PageLoadTiming & timing)391   virtual void OnFirstImagePaintInPage(const mojom::PageLoadTiming& timing) {}
OnFirstContentfulPaintInPage(const mojom::PageLoadTiming & timing)392   virtual void OnFirstContentfulPaintInPage(
393       const mojom::PageLoadTiming& timing) {}
394 
395   // These are called once every time when the page is restored from the
396   // back-forward cache. |index| indicates |index|-th restore.
OnFirstPaintAfterBackForwardCacheRestoreInPage(const mojom::BackForwardCacheTiming & timing,size_t index)397   virtual void OnFirstPaintAfterBackForwardCacheRestoreInPage(
398       const mojom::BackForwardCacheTiming& timing,
399       size_t index) {}
OnFirstInputAfterBackForwardCacheRestoreInPage(const mojom::BackForwardCacheTiming & timing,size_t index)400   virtual void OnFirstInputAfterBackForwardCacheRestoreInPage(
401       const mojom::BackForwardCacheTiming& timing,
402       size_t index) {}
403 
404   // This is called several times on requestAnimationFrame after the page is
405   // restored from the back-forward cache. The number of the calls is hard-
406   // coded as WebPerformance::
407   // kRequestAnimationFramesToRecordAfterBackForwardCacheRestore.
OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(const mojom::BackForwardCacheTiming & timing)408   virtual void OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(
409       const mojom::BackForwardCacheTiming& timing) {}
410 
411   // Unlike other paint callbacks, OnFirstMeaningfulPaintInMainFrameDocument is
412   // tracked per document, and is reported for the main frame document only.
OnFirstMeaningfulPaintInMainFrameDocument(const mojom::PageLoadTiming & timing)413   virtual void OnFirstMeaningfulPaintInMainFrameDocument(
414       const mojom::PageLoadTiming& timing) {}
415 
OnFirstInputInPage(const mojom::PageLoadTiming & timing)416   virtual void OnFirstInputInPage(const mojom::PageLoadTiming& timing) {}
417 
418   // Invoked when there is an update to the loading behavior_flags in the given
419   // frame.
OnLoadingBehaviorObserved(content::RenderFrameHost * rfh,int behavior_flags)420   virtual void OnLoadingBehaviorObserved(content::RenderFrameHost* rfh,
421                                          int behavior_flags) {}
422 
423   // Invoked when new use counter features are observed across all frames.
OnFeaturesUsageObserved(content::RenderFrameHost * rfh,const mojom::PageLoadFeatures & features)424   virtual void OnFeaturesUsageObserved(
425       content::RenderFrameHost* rfh,
426       const mojom::PageLoadFeatures& features) {}
427 
428   // The smoothness metrics is shared over shared-memory. The observer should
429   // create a mapping (by calling |shared_memory.Map()|) so that they are able
430   // to read from the shared memory.
SetUpSharedMemoryForSmoothness(const base::ReadOnlySharedMemoryRegion & shared_memory)431   virtual void SetUpSharedMemoryForSmoothness(
432       const base::ReadOnlySharedMemoryRegion& shared_memory) {}
433 
434   // Invoked when there is data use for loading a resource on the page
435   // for a given render frame host. This only contains resources that have had
436   // new data use since the last callback. Resources loaded from the cache only
437   // receive a single update. Multiple updates can be received for the same
438   // resource if it is loaded in multiple documents.
OnResourceDataUseObserved(content::RenderFrameHost * rfh,const std::vector<mojom::ResourceDataUpdatePtr> & resources)439   virtual void OnResourceDataUseObserved(
440       content::RenderFrameHost* rfh,
441       const std::vector<mojom::ResourceDataUpdatePtr>& resources) {}
442 
443   // Invoked when there is new information about lazy loaded or deferred
444   // resources. |new_deferred_resource_data| only has new deferral/lazy load
445   // events since the last update.
OnNewDeferredResourceCounts(const mojom::DeferredResourceCounts & new_deferred_resource_data)446   virtual void OnNewDeferredResourceCounts(
447       const mojom::DeferredResourceCounts& new_deferred_resource_data) {}
448 
449   // Invoked when a media element starts playing.
MediaStartedPlaying(const content::WebContentsObserver::MediaPlayerInfo & video_type,content::RenderFrameHost * render_frame_host)450   virtual void MediaStartedPlaying(
451       const content::WebContentsObserver::MediaPlayerInfo& video_type,
452       content::RenderFrameHost* render_frame_host) {}
453 
454   // Invoked when a frame's intersections with page elements changes and an
455   // update is received. The main_frame_document_intersection_rect
456   // returns an empty rect for out of view subframes and the root document size
457   // for the main frame.
458   // TODO(crbug/1048175): Expose intersections to observers via shared delegate.
OnFrameIntersectionUpdate(content::RenderFrameHost * rfh,const mojom::FrameIntersectionUpdate & intersection_update)459   virtual void OnFrameIntersectionUpdate(
460       content::RenderFrameHost* rfh,
461       const mojom::FrameIntersectionUpdate& intersection_update) {}
462 
463   // Invoked when the UMA metrics subsystem is persisting metrics as the
464   // application goes into the background, on platforms where the browser
465   // process may be killed after backgrounding (Android). Implementers should
466   // persist any metrics that have been buffered in memory in this callback, as
467   // the application may be killed at any time after this method is invoked
468   // without further notification. Note that this may be called both for
469   // provisional loads as well as committed loads. Implementations that only
470   // want to track committed loads should check GetDelegate().DidCommit()
471   // to determine if the load had committed. If the implementation returns
472   // CONTINUE_OBSERVING, this method may be called multiple times per observer,
473   // once for each time that the application enters the background.
474   //
475   // The default implementation does nothing, and returns CONTINUE_OBSERVING.
476   virtual ObservePolicy FlushMetricsOnAppEnterBackground(
477       const mojom::PageLoadTiming& timing);
478 
479   // One of OnComplete or OnFailedProvisionalLoad is invoked for tracked page
480   // loads, immediately before the observer is deleted. These callbacks will not
481   // be invoked for page loads that did not meet the criteria for being tracked
482   // at the time the navigation completed. The PageLoadTiming struct contains
483   // timing data. Other useful data collected over the course of the page load
484   // is exposed by the observer delegate API. Most observers should not need
485   // to implement these callbacks, and should implement the On* timing callbacks
486   // instead.
487 
488   // OnComplete is invoked for tracked page loads that committed, immediately
489   // before the observer is deleted. Observers that implement OnComplete may
490   // also want to implement FlushMetricsOnAppEnterBackground, to avoid loss of
491   // data if the application is killed while in the background (this happens
492   // frequently on Android).
OnComplete(const mojom::PageLoadTiming & timing)493   virtual void OnComplete(const mojom::PageLoadTiming& timing) {}
494 
495   // OnFailedProvisionalLoad is invoked for tracked page loads that did not
496   // commit, immediately before the observer is deleted.
OnFailedProvisionalLoad(const FailedProvisionalLoadInfo & failed_provisional_load_info)497   virtual void OnFailedProvisionalLoad(
498       const FailedProvisionalLoadInfo& failed_provisional_load_info) {}
499 
500   // Called whenever a request is loaded for this page load. This is restricted
501   // to requests with HTTP or HTTPS only schemes.
OnLoadedResource(const ExtraRequestCompleteInfo & extra_request_complete_info)502   virtual void OnLoadedResource(
503       const ExtraRequestCompleteInfo& extra_request_complete_info) {}
504 
FrameReceivedFirstUserActivation(content::RenderFrameHost * render_frame_host)505   virtual void FrameReceivedFirstUserActivation(
506       content::RenderFrameHost* render_frame_host) {}
507 
508   // Called when the display property changes on the frame.
FrameDisplayStateChanged(content::RenderFrameHost * render_frame_host,bool is_display_none)509   virtual void FrameDisplayStateChanged(
510       content::RenderFrameHost* render_frame_host,
511       bool is_display_none) {}
512 
513   // Called when a frames size changes.
FrameSizeChanged(content::RenderFrameHost * render_frame_host,const gfx::Size & frame_size)514   virtual void FrameSizeChanged(content::RenderFrameHost* render_frame_host,
515                                 const gfx::Size& frame_size) {}
516 
OnFrameDeleted(content::RenderFrameHost * render_frame_host)517   virtual void OnFrameDeleted(content::RenderFrameHost* render_frame_host) {}
518 
519   // Called when a cookie is read for a resource request or by document.cookie.
OnCookiesRead(const GURL & url,const GURL & first_party_url,const net::CookieList & cookie_list,bool blocked_by_policy)520   virtual void OnCookiesRead(const GURL& url,
521                              const GURL& first_party_url,
522                              const net::CookieList& cookie_list,
523                              bool blocked_by_policy) {}
524 
525   // Called when a cookie is set by a header or via document.cookie.
OnCookieChange(const GURL & url,const GURL & first_party_url,const net::CanonicalCookie & cookie,bool blocked_by_policy)526   virtual void OnCookieChange(const GURL& url,
527                               const GURL& first_party_url,
528                               const net::CanonicalCookie& cookie,
529                               bool blocked_by_policy) {}
530 
531   // Called when a storage access attempt by the origin |url| to |storage_type|
532   // is checked by the content settings manager. |blocked_by_policy| is false
533   // when cookie access is not allowed for |url|.
OnStorageAccessed(const GURL & url,const GURL & first_party_url,bool blocked_by_policy,StorageType access_type)534   virtual void OnStorageAccessed(const GURL& url,
535                                  const GURL& first_party_url,
536                                  bool blocked_by_policy,
537                                  StorageType access_type) {}
538 
539   // Called when the event corresponding to |event_key| occurs in this page
540   // load.
OnEventOccurred(const void * const event_key)541   virtual void OnEventOccurred(const void* const event_key) {}
542 
543   // Called when the page tracked was just activated after being loaded inside a
544   // portal.
DidActivatePortal(base::TimeTicks activation_time)545   virtual void DidActivatePortal(base::TimeTicks activation_time) {}
546 
547  private:
548   PageLoadMetricsObserverDelegate* delegate_ = nullptr;
549 };
550 
551 }  // namespace page_load_metrics
552 
553 #endif  // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_
554