Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/browser/page_load_metrics/page_load_tracker.h

Issue 2699933003: Generalize abort tracking to page end state tracking (Closed)
Patch Set: add additional histogram Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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,
Charlie Harrison 2017/02/21 19:49:31 please update the histograms xml file for this.
Bryan McQuade 2017/02/21 21:51:59 Done, thanks!
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698