OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ | 5 #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ |
6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ | 6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // We received an IPC even through the last committed url from the browser | 70 // We received an IPC even through the last committed url from the browser |
71 // was not http/s. This can happen with the renderer sending IPCs for the | 71 // was not http/s. This can happen with the renderer sending IPCs for the |
72 // new tab page. This will often come paired with | 72 // new tab page. This will often come paired with |
73 // ERR_IPC_WITH_NO_RELEVANT_LOAD. | 73 // ERR_IPC_WITH_NO_RELEVANT_LOAD. |
74 ERR_IPC_FROM_BAD_URL_SCHEME, | 74 ERR_IPC_FROM_BAD_URL_SCHEME, |
75 | 75 |
76 // If we track a navigation, but the renderer sends us no IPCs. This could | 76 // If we track a navigation, but the renderer sends us no IPCs. This could |
77 // occur if the browser filters loads less aggressively than the renderer. | 77 // occur if the browser filters loads less aggressively than the renderer. |
78 ERR_NO_IPCS_RECEIVED, | 78 ERR_NO_IPCS_RECEIVED, |
79 | 79 |
80 // Tracks frequency with which we record an abort time that occurred before | 80 // Tracks frequency with which we record an end time that occurred before |
81 // navigation start. This is expected to happen in some cases (see comments in | 81 // navigation start. This is expected to happen in some cases (see comments in |
82 // cc file for details). We use this error counter to understand how often it | 82 // cc file for details). We use this error counter to understand how often it |
83 // happens. | 83 // happens. |
84 ERR_ABORT_BEFORE_NAVIGATION_START, | 84 ERR_END_BEFORE_NAVIGATION_START, |
85 | 85 |
86 // A new navigation triggers abort updates in multiple trackers in | 86 // A new navigation triggers abort updates in multiple trackers in |
87 // |aborted_provisional_loads_|, when usually there should only be one (the | 87 // |aborted_provisional_loads_|, when usually there should only be one (the |
88 // navigation that just aborted because of this one). If this happens, the | 88 // navigation that just aborted because of this one). If this happens, the |
89 // latest aborted load is used to track the chain size. | 89 // latest aborted load is used to track the chain size. |
90 ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS, | 90 ERR_NAVIGATION_SIGNALS_MULIPLE_ABORTED_LOADS, |
91 | 91 |
92 // Received user input without a relevant load. This error type is deprecated, | 92 // Received user input without a relevant load. This error type is deprecated, |
93 // as it is valid to receive user input without a relevant load. We leave the | 93 // as it is valid to receive user input without a relevant load. We leave the |
94 // enum value here since it's also used in histogram recording, so it's | 94 // enum value here since it's also used in histogram recording, so it's |
95 // important that we not re-use this enum entry for a different value. | 95 // important that we not re-use this enum entry for a different value. |
96 DEPRECATED_ERR_USER_INPUT_WITH_NO_RELEVANT_LOAD, | 96 DEPRECATED_ERR_USER_INPUT_WITH_NO_RELEVANT_LOAD, |
97 | 97 |
98 // A TimeTicks value in the browser process has value less than | 98 // A TimeTicks value in the browser process has value less than |
99 // navigation_start_. This could happen if navigation_start_ was computed in | 99 // navigation_start_. This could happen if navigation_start_ was computed in |
100 // renderer process and the system clock has inter process time tick skew. | 100 // renderer process and the system clock has inter process time tick skew. |
101 ERR_INTER_PROCESS_TIME_TICK_SKEW, | 101 ERR_INTER_PROCESS_TIME_TICK_SKEW, |
102 | 102 |
103 // At the time a PageLoadTracker was destroyed, we had received neither a | 103 // At the time a PageLoadTracker was destroyed, we had received neither a |
104 // commit nor a failed provisional load. | 104 // commit nor a failed provisional load. |
105 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD, | 105 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD, |
106 | 106 |
| 107 // No page load end time was recorded for this page load. |
| 108 ERR_NO_PAGE_LOAD_END_TIME, |
| 109 |
107 // Add values before this final count. | 110 // Add values before this final count. |
108 ERR_LAST_ENTRY, | 111 ERR_LAST_ENTRY, |
109 }; | 112 }; |
110 | 113 |
111 // NOTE: these functions are shared by page_load_tracker.cc and | 114 // NOTE: these functions are shared by page_load_tracker.cc and |
112 // metrics_web_contents_observer.cc. They are declared here to allow both files | 115 // metrics_web_contents_observer.cc. They are declared here to allow both files |
113 // to access them. | 116 // to access them. |
114 void RecordInternalError(InternalErrorLoadEvent event); | 117 void RecordInternalError(InternalErrorLoadEvent event); |
115 UserAbortType AbortTypeForPageTransition(ui::PageTransition transition); | 118 PageEndReason EndReasonForPageTransition(ui::PageTransition transition); |
116 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); | 119 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); |
117 bool IsNavigationUserInitiated(content::NavigationHandle* handle); | 120 bool IsNavigationUserInitiated(content::NavigationHandle* handle); |
118 | 121 |
119 // This class tracks a given page load, starting from navigation start / | 122 // This class tracks a given page load, starting from navigation start / |
120 // provisional load, until a new navigation commits or the navigation fails. | 123 // provisional load, until a new navigation commits or the navigation fails. |
121 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as | 124 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as |
122 // well as a committed PageLoadTracker. | 125 // well as a committed PageLoadTracker. |
123 class PageLoadTracker { | 126 class PageLoadTracker { |
124 public: | 127 public: |
125 // Caller must guarantee that the embedder_interface pointer outlives this | 128 // Caller must guarantee that the embedder_interface pointer outlives this |
126 // class. The PageLoadTracker must not hold on to | 129 // class. The PageLoadTracker must not hold on to |
127 // currently_committed_load_or_null or navigation_handle beyond the scope of | 130 // currently_committed_load_or_null or navigation_handle beyond the scope of |
128 // the constructor. | 131 // the constructor. |
129 PageLoadTracker(bool in_foreground, | 132 PageLoadTracker(bool in_foreground, |
130 PageLoadMetricsEmbedderInterface* embedder_interface, | 133 PageLoadMetricsEmbedderInterface* embedder_interface, |
131 const GURL& currently_committed_url, | 134 const GURL& currently_committed_url, |
132 content::NavigationHandle* navigation_handle, | 135 content::NavigationHandle* navigation_handle, |
133 UserInitiatedInfo user_initiated_info, | 136 UserInitiatedInfo user_initiated_info, |
134 int aborted_chain_size, | 137 int aborted_chain_size, |
135 int aborted_chain_size_same_url); | 138 int aborted_chain_size_same_url); |
136 ~PageLoadTracker(); | 139 ~PageLoadTracker(); |
137 void Redirect(content::NavigationHandle* navigation_handle); | 140 void Redirect(content::NavigationHandle* navigation_handle); |
138 void WillProcessNavigationResponse( | 141 void WillProcessNavigationResponse( |
139 content::NavigationHandle* navigation_handle); | 142 content::NavigationHandle* navigation_handle); |
140 void Commit(content::NavigationHandle* navigation_handle); | 143 void Commit(content::NavigationHandle* navigation_handle); |
141 void FailedProvisionalLoad(content::NavigationHandle* navigation_handle); | 144 void FailedProvisionalLoad(content::NavigationHandle* navigation_handle, |
| 145 base::TimeTicks failed_load_time); |
142 void WebContentsHidden(); | 146 void WebContentsHidden(); |
143 void WebContentsShown(); | 147 void WebContentsShown(); |
144 | 148 |
145 void OnInputEvent(const blink::WebInputEvent& event); | 149 void OnInputEvent(const blink::WebInputEvent& event); |
146 | 150 |
147 // Flush any buffered metrics, as part of the metrics subsystem persisting | 151 // Flush any buffered metrics, as part of the metrics subsystem persisting |
148 // metrics as the application goes into the background. The application may be | 152 // metrics as the application goes into the background. The application may be |
149 // killed at any time after this method is invoked without further | 153 // killed at any time after this method is invoked without further |
150 // notification. | 154 // notification. |
151 void FlushMetricsOnAppEnterBackground(); | 155 void FlushMetricsOnAppEnterBackground(); |
152 | 156 |
153 void NotifyClientRedirectTo(const PageLoadTracker& destination); | 157 void NotifyClientRedirectTo(const PageLoadTracker& destination); |
154 | 158 |
155 // Returns true if the timing was successfully updated. | 159 // Returns true if the timing was successfully updated. |
156 bool UpdateTiming(const PageLoadTiming& timing, | 160 bool UpdateTiming(const PageLoadTiming& timing, |
157 const PageLoadMetadata& metadata); | 161 const PageLoadMetadata& metadata); |
158 | 162 |
159 void OnLoadedResource(const ExtraRequestInfo& extra_request_info); | 163 void OnLoadedResource(const ExtraRequestInfo& extra_request_info); |
160 | 164 |
161 // Signals that we should stop tracking metrics for the associated page load. | 165 // Signals that we should stop tracking metrics for the associated page load. |
162 // We may stop tracking a page load if it doesn't meet the criteria for | 166 // We may stop tracking a page load if it doesn't meet the criteria for |
163 // tracking metrics in DidFinishNavigation. | 167 // tracking metrics in DidFinishNavigation. |
164 void StopTracking(); | 168 void StopTracking(); |
165 | 169 |
166 int aborted_chain_size() const { return aborted_chain_size_; } | 170 int aborted_chain_size() const { return aborted_chain_size_; } |
167 int aborted_chain_size_same_url() const { | 171 int aborted_chain_size_same_url() const { |
168 return aborted_chain_size_same_url_; | 172 return aborted_chain_size_same_url_; |
169 } | 173 } |
170 | 174 |
171 UserAbortType abort_type() const { return abort_type_; } | 175 PageEndReason page_end_reason() const { return page_end_reason_; } |
172 base::TimeTicks abort_time() const { return abort_time_; } | 176 base::TimeTicks page_end_time() const { return page_end_time_; } |
173 | 177 |
174 void AddObserver(std::unique_ptr<PageLoadMetricsObserver> observer); | 178 void AddObserver(std::unique_ptr<PageLoadMetricsObserver> observer); |
175 | 179 |
176 // If the user performs some abort-like action while we are tracking this page | 180 // If the user performs some abort-like action while we are tracking this page |
177 // load, notify the tracker. Note that we may not classify this as an abort if | 181 // load, notify the tracker. Note that we may not classify this as an abort if |
178 // we've already performed a first paint. | 182 // we've already performed a first paint. |
179 // is_certainly_browser_timestamp signifies if the timestamp passed is taken | 183 // is_certainly_browser_timestamp signifies if the timestamp passed is taken |
180 // in the | 184 // in the |
181 // browser process or not. We need this to possibly clamp browser timestamp on | 185 // browser process or not. We need this to possibly clamp browser timestamp on |
182 // a machine with inter process time tick skew. | 186 // a machine with inter process time tick skew. |
183 void NotifyAbort(UserAbortType abort_type, | 187 void NotifyPageEnd(PageEndReason page_end_reason, |
184 UserInitiatedInfo user_initiated_info, | 188 UserInitiatedInfo user_initiated_info, |
185 base::TimeTicks timestamp, | 189 base::TimeTicks timestamp, |
186 bool is_certainly_browser_timestamp); | 190 bool is_certainly_browser_timestamp); |
187 void UpdateAbort(UserAbortType abort_type, | 191 void UpdatePageEnd(PageEndReason page_end_reason, |
188 UserInitiatedInfo user_initiated_info, | 192 UserInitiatedInfo user_initiated_info, |
189 base::TimeTicks timestamp, | 193 base::TimeTicks timestamp, |
190 bool is_certainly_browser_timestamp); | 194 bool is_certainly_browser_timestamp); |
191 | 195 |
192 // This method returns true if this page load has been aborted with type of | 196 // This method returns true if this page load has been aborted with type of |
193 // ABORT_OTHER, and the |abort_cause_time| is within a sufficiently close | 197 // END_OTHER, and the |abort_cause_time| is within a sufficiently close |
194 // delta to when it was aborted. Note that only provisional loads can be | 198 // delta to when it was aborted. Note that only provisional loads can be |
195 // aborted with ABORT_OTHER. While this heuristic is coarse, it works better | 199 // aborted with END_OTHER. While this heuristic is coarse, it works better |
196 // and is simpler than other feasible methods. See https://goo.gl/WKRG98. | 200 // and is simpler than other feasible methods. See https://goo.gl/WKRG98. |
197 bool IsLikelyProvisionalAbort(base::TimeTicks abort_cause_time) const; | 201 bool IsLikelyProvisionalAbort(base::TimeTicks abort_cause_time) const; |
198 | 202 |
199 bool MatchesOriginalNavigation(content::NavigationHandle* navigation_handle); | 203 bool MatchesOriginalNavigation(content::NavigationHandle* navigation_handle); |
200 | 204 |
201 bool did_commit() const { return did_commit_; } | 205 bool did_commit() const { return did_commit_; } |
202 const GURL& url() const { return url_; } | 206 const GURL& url() const { return url_; } |
203 | 207 |
204 base::TimeTicks navigation_start() const { return navigation_start_; } | 208 base::TimeTicks navigation_start() const { return navigation_start_; } |
205 | 209 |
(...skipping 15 matching lines...) Expand all Loading... |
221 | 225 |
222 private: | 226 private: |
223 // This function converts a TimeTicks value taken in the browser process | 227 // This function converts a TimeTicks value taken in the browser process |
224 // to navigation_start_ if: | 228 // to navigation_start_ if: |
225 // - base::TimeTicks is not comparable across processes because the clock | 229 // - base::TimeTicks is not comparable across processes because the clock |
226 // is not system wide monotonic. | 230 // is not system wide monotonic. |
227 // - *event_time < navigation_start_ | 231 // - *event_time < navigation_start_ |
228 void ClampBrowserTimestampIfInterProcessTimeTickSkew( | 232 void ClampBrowserTimestampIfInterProcessTimeTickSkew( |
229 base::TimeTicks* event_time); | 233 base::TimeTicks* event_time); |
230 | 234 |
231 void UpdateAbortInternal(UserAbortType abort_type, | 235 void UpdatePageEndInternal(PageEndReason page_end_reason, |
232 UserInitiatedInfo user_initiated_info, | 236 UserInitiatedInfo user_initiated_info, |
233 base::TimeTicks timestamp, | 237 base::TimeTicks timestamp, |
234 bool is_certainly_browser_timestamp); | 238 bool is_certainly_browser_timestamp); |
235 | 239 |
236 // If |final_navigation| is null, then this is an "unparented" abort chain, | 240 // If |final_navigation| is null, then this is an "unparented" abort chain, |
237 // and represents a sequence of provisional aborts that never ends with a | 241 // and represents a sequence of provisional aborts that never ends with a |
238 // committed load. | 242 // committed load. |
239 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); | 243 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); |
240 | 244 |
241 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); | 245 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); |
242 | 246 |
243 UserInputTracker input_tracker_; | 247 UserInputTracker input_tracker_; |
244 | 248 |
(...skipping 14 matching lines...) Expand all Loading... |
259 GURL url_; | 263 GURL url_; |
260 | 264 |
261 // The start URL for this page load (before redirects). | 265 // The start URL for this page load (before redirects). |
262 GURL start_url_; | 266 GURL start_url_; |
263 | 267 |
264 // Whether this page load committed. | 268 // Whether this page load committed. |
265 bool did_commit_; | 269 bool did_commit_; |
266 | 270 |
267 std::unique_ptr<FailedProvisionalLoadInfo> failed_provisional_load_info_; | 271 std::unique_ptr<FailedProvisionalLoadInfo> failed_provisional_load_info_; |
268 | 272 |
269 // Will be ABORT_NONE if we have not aborted this load yet. Otherwise will | 273 // Will be END_NONE if we have not ended this load yet. Otherwise will |
270 // be the first abort action the user performed. | 274 // be the first page end reason encountered. |
271 UserAbortType abort_type_; | 275 PageEndReason page_end_reason_; |
272 | 276 |
273 // Whether the abort for this page load was user initiated. For example, if | 277 // Whether the page end cause for this page load was user initiated. For |
274 // this page load was aborted by a new navigation, this field tracks whether | 278 // example, if this page load was ended by a new navigation, this field tracks |
275 // that new navigation was user-initiated. This field is only useful if this | 279 // whether that new navigation was user-initiated. This field is only useful |
276 // page load's abort type is a value other than ABORT_NONE. Note that this | 280 // if this page load's end reason is a value other than END_NONE. Note that |
277 // value is currently experimental, and is subject to change. In particular, | 281 // this value is currently experimental, and is subject to change. In |
278 // this field is never set to true for some abort types, such as stop and | 282 // particular, this field is never set to true for some page end reasons, such |
279 // close, since we don't yet have sufficient instrumentation to know if a stop | 283 // as stop and close, since we don't yet have sufficient instrumentation to |
280 // or close was caused by a user action. | 284 // know if a stop or close was caused by a user action. |
281 UserInitiatedInfo abort_user_initiated_info_; | 285 UserInitiatedInfo page_end_user_initiated_info_; |
282 | 286 |
283 base::TimeTicks abort_time_; | 287 base::TimeTicks page_end_time_; |
284 | 288 |
285 // We record separate metrics for events that occur after a background, | 289 // We record separate metrics for events that occur after a background, |
286 // because metrics like layout/paint are delayed artificially | 290 // because metrics like layout/paint are delayed artificially |
287 // when they occur in the background. | 291 // when they occur in the background. |
288 base::TimeTicks background_time_; | 292 base::TimeTicks background_time_; |
289 base::TimeTicks foreground_time_; | 293 base::TimeTicks foreground_time_; |
290 bool started_in_foreground_; | 294 bool started_in_foreground_; |
291 | 295 |
292 PageLoadTiming timing_; | 296 PageLoadTiming timing_; |
293 PageLoadMetadata metadata_; | 297 PageLoadMetadata metadata_; |
(...skipping 21 matching lines...) Expand all Loading... |
315 PageLoadMetricsEmbedderInterface* const embedder_interface_; | 319 PageLoadMetricsEmbedderInterface* const embedder_interface_; |
316 | 320 |
317 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; | 321 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; |
318 | 322 |
319 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); | 323 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); |
320 }; | 324 }; |
321 | 325 |
322 } // namespace page_load_metrics | 326 } // namespace page_load_metrics |
323 | 327 |
324 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ | 328 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ |
OLD | NEW |