| 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 |