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 CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_FROM_GWS_PAGE_LOAD_METRICS_OBSERVER_H_
6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_FROM_GWS_PAGE_LOAD_METRICS_OBSERVER_H_
7 
8 #include "base/macros.h"
9 #include "base/optional.h"
10 #include "components/page_load_metrics/browser/page_load_metrics_observer.h"
11 #include "services/metrics/public/cpp/ukm_source.h"
12 #include "url/gurl.h"
13 
14 namespace internal {
15 // Exposed for tests.
16 extern const char kHistogramFromGWSDomContentLoaded[];
17 extern const char kHistogramFromGWSLoad[];
18 extern const char kHistogramFromGWSFirstPaint[];
19 extern const char kHistogramFromGWSFirstImagePaint[];
20 extern const char kHistogramFromGWSFirstContentfulPaint[];
21 extern const char kHistogramFromGWSLargestContentfulPaint[];
22 extern const char kHistogramFromGWSParseStartToFirstContentfulPaint[];
23 extern const char kHistogramFromGWSParseDuration[];
24 extern const char kHistogramFromGWSParseStart[];
25 extern const char kHistogramFromGWSFirstInputDelay[];
26 extern const char kHistogramFromGWSAbortStopBeforePaint[];
27 extern const char kHistogramFromGWSAbortStopBeforeInteraction[];
28 extern const char kHistogramFromGWSAbortStopBeforeCommit[];
29 extern const char kHistogramFromGWSAbortCloseBeforePaint[];
30 extern const char kHistogramFromGWSAbortCloseBeforeInteraction[];
31 extern const char kHistogramFromGWSAbortCloseBeforeCommit[];
32 extern const char kHistogramFromGWSAbortNewNavigationBeforeCommit[];
33 extern const char kHistogramFromGWSAbortNewNavigationBeforePaint[];
34 extern const char kHistogramFromGWSAbortNewNavigationBeforeInteraction[];
35 extern const char kHistogramFromGWSAbortReloadBeforeInteraction[];
36 extern const char kHistogramFromGWSForegroundDuration[];
37 extern const char kHistogramFromGWSForegroundDurationAfterPaint[];
38 extern const char kHistogramFromGWSForegroundDurationNoCommit[];
39 extern const char kHistogramFromGWSCumulativeLayoutShiftMainFrame[];
40 
41 }  // namespace internal
42 
43 // FromGWSPageLoadMetricsLogger is a peer class to
44 // FromGWSPageLoadMetricsObserver. FromGWSPageLoadMetricsLogger is responsible
45 // for tracking state needed to decide if metrics should be logged, and to log
46 // metrics in cases where metrics should be logged. FromGWSPageLoadMetricsLogger
47 // exists to decouple the logging policy implementation from other Chromium
48 // classes such as NavigationHandle and related infrastructure, in order to make
49 // the code more unit testable.
50 class FromGWSPageLoadMetricsLogger {
51  public:
52   FromGWSPageLoadMetricsLogger();
53   ~FromGWSPageLoadMetricsLogger();
54 
55   void SetPreviouslyCommittedUrl(const GURL& url);
56   void SetProvisionalUrl(const GURL& url);
57 
set_navigation_initiated_via_link(bool navigation_initiated_via_link)58   void set_navigation_initiated_via_link(bool navigation_initiated_via_link) {
59     navigation_initiated_via_link_ = navigation_initiated_via_link;
60   }
61 
SetNavigationStart(const base::TimeTicks navigation_start)62   void SetNavigationStart(const base::TimeTicks navigation_start) {
63     // Should be invoked at most once
64     DCHECK(navigation_start_.is_null());
65     navigation_start_ = navigation_start;
66   }
67 
68   // Invoked when metrics for the given page are complete.
69   void OnCommit(content::NavigationHandle* navigation_handle,
70                 ukm::SourceId source_id);
71   // TODO(crbug/993377): Replace const& to PageLoadMetricsObserverDelegate with
72   // a member variable.
73   void OnComplete(
74       const page_load_metrics::mojom::PageLoadTiming& timing,
75       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
76   void OnFailedProvisionalLoad(
77       const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info,
78       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
79 
80   void OnDomContentLoadedEventStart(
81       const page_load_metrics::mojom::PageLoadTiming& timing,
82       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
83   void OnLoadEventStart(
84       const page_load_metrics::mojom::PageLoadTiming& timing,
85       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
86   void OnFirstPaintInPage(
87       const page_load_metrics::mojom::PageLoadTiming& timing,
88       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
89   void OnFirstImagePaintInPage(
90       const page_load_metrics::mojom::PageLoadTiming& timing,
91       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
92   void OnFirstContentfulPaintInPage(
93       const page_load_metrics::mojom::PageLoadTiming& timing,
94       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
95   void OnParseStart(
96       const page_load_metrics::mojom::PageLoadTiming& timing,
97       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
98   void OnParseStop(
99       const page_load_metrics::mojom::PageLoadTiming& timing,
100       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
101   void OnUserInput(
102       const blink::WebInputEvent& event,
103       const page_load_metrics::mojom::PageLoadTiming& timing,
104       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
105   void OnFirstInputInPage(
106       const page_load_metrics::mojom::PageLoadTiming& timing,
107       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
108   void FlushMetricsOnAppEnterBackground(
109       const page_load_metrics::mojom::PageLoadTiming& timing,
110       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
111 
112   // The methods below are public only for testing.
113   bool ShouldLogFailedProvisionalLoadMetrics();
114   bool ShouldLogPostCommitMetrics(const GURL& url);
115   bool ShouldLogForegroundEventAfterCommit(
116       const base::Optional<base::TimeDelta>& event,
117       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
118 
119  private:
120   void LogMetricsOnComplete(
121       const page_load_metrics::PageLoadMetricsObserverDelegate& delegate);
122 
123   bool previously_committed_url_is_search_results_ = false;
124   bool previously_committed_url_is_search_redirector_ = false;
125   bool navigation_initiated_via_link_ = false;
126   bool provisional_url_has_search_hostname_ = false;
127 
128   // The state of if first paint is triggered.
129   bool first_paint_triggered_ = false;
130 
131   base::TimeTicks navigation_start_;
132 
133   // The time of first user interaction after paint from navigation start.
134   base::Optional<base::TimeDelta> first_user_interaction_after_paint_;
135 
136   DISALLOW_COPY_AND_ASSIGN(FromGWSPageLoadMetricsLogger);
137 };
138 
139 class FromGWSPageLoadMetricsObserver
140     : public page_load_metrics::PageLoadMetricsObserver {
141  public:
142   FromGWSPageLoadMetricsObserver();
143 
144   // page_load_metrics::PageLoadMetricsObserver implementation:
145   ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
146                          const GURL& currently_committed_url,
147                          bool started_in_foreground) override;
148   ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
149                          ukm::SourceId source_id) override;
150 
151   ObservePolicy FlushMetricsOnAppEnterBackground(
152       const page_load_metrics::mojom::PageLoadTiming& timing) override;
153 
154   void OnDomContentLoadedEventStart(
155       const page_load_metrics::mojom::PageLoadTiming& timing) override;
156   void OnLoadEventStart(
157       const page_load_metrics::mojom::PageLoadTiming& timing) override;
158   void OnFirstPaintInPage(
159       const page_load_metrics::mojom::PageLoadTiming& timing) override;
160   void OnFirstImagePaintInPage(
161       const page_load_metrics::mojom::PageLoadTiming& timing) override;
162   void OnFirstContentfulPaintInPage(
163       const page_load_metrics::mojom::PageLoadTiming& timing) override;
164   void OnFirstInputInPage(
165       const page_load_metrics::mojom::PageLoadTiming& timing) override;
166   void OnParseStart(
167       const page_load_metrics::mojom::PageLoadTiming& timing) override;
168   void OnParseStop(
169       const page_load_metrics::mojom::PageLoadTiming& timing) override;
170 
171   void OnComplete(
172       const page_load_metrics::mojom::PageLoadTiming& timing) override;
173   void OnFailedProvisionalLoad(
174       const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info)
175       override;
176 
177   void OnUserInput(
178       const blink::WebInputEvent& event,
179       const page_load_metrics::mojom::PageLoadTiming& timing) override;
180 
181  private:
182   FromGWSPageLoadMetricsLogger logger_;
183 
184   DISALLOW_COPY_AND_ASSIGN(FromGWSPageLoadMetricsObserver);
185 };
186 
187 #endif  // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_FROM_GWS_PAGE_LOAD_METRICS_OBSERVER_H_
188