Chromium Code Reviews| 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 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/optional.h" | 12 #include "base/optional.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" | 14 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" |
| 15 #include "chrome/browser/page_load_metrics/user_input_tracker.h" | 15 #include "chrome/browser/page_load_metrics/user_input_tracker.h" |
| 16 #include "chrome/common/page_load_metrics/page_load_timing.h" | 16 #include "chrome/common/page_load_metrics/page_load_timing.h" |
| 17 #include "content/public/browser/global_request_id.h" | 17 #include "content/public/browser/global_request_id.h" |
| 18 #include "content/public/browser/web_contents_observer.h" | 18 #include "content/public/browser/web_contents_observer.h" |
| 19 #include "ui/base/page_transition_types.h" | 19 #include "ui/base/page_transition_types.h" |
| 20 | 20 |
| 21 class GURL; | 21 class GURL; |
| 22 | 22 |
| 23 namespace blink { | 23 namespace blink { |
| 24 class WebInputEvent; | 24 class WebInputEvent; |
| 25 } // namespace blink | 25 } // namespace blink |
| 26 | 26 |
| 27 namespace content { | 27 namespace content { |
| 28 class NavigationHandle; | 28 class NavigationHandle; |
| 29 class RenderFrameHost; | |
| 29 } // namespace content | 30 } // namespace content |
| 30 | 31 |
| 31 namespace page_load_metrics { | 32 namespace page_load_metrics { |
| 32 | 33 |
| 33 class PageLoadMetricsEmbedderInterface; | 34 class PageLoadMetricsEmbedderInterface; |
| 34 class PageLoadMetricsObserver; | 35 class PageLoadMetricsObserver; |
| 35 | 36 |
| 36 namespace internal { | 37 namespace internal { |
| 37 | 38 |
| 38 extern const char kErrorEvents[]; | 39 extern const char kErrorEvents[]; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 // renderer process and the system clock has inter process time tick skew. | 146 // renderer process and the system clock has inter process time tick skew. |
| 146 ERR_INTER_PROCESS_TIME_TICK_SKEW, | 147 ERR_INTER_PROCESS_TIME_TICK_SKEW, |
| 147 | 148 |
| 148 // At the time a PageLoadTracker was destroyed, we had received neither a | 149 // At the time a PageLoadTracker was destroyed, we had received neither a |
| 149 // commit nor a failed provisional load. | 150 // commit nor a failed provisional load. |
| 150 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD, | 151 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD, |
| 151 | 152 |
| 152 // No page load end time was recorded for this page load. | 153 // No page load end time was recorded for this page load. |
| 153 ERR_NO_PAGE_LOAD_END_TIME, | 154 ERR_NO_PAGE_LOAD_END_TIME, |
| 154 | 155 |
| 155 // Received a timing update from a subframe. | 156 // Received a timing update from a subframe (deprecated). |
| 156 ERR_TIMING_IPC_FROM_SUBFRAME, | 157 DEPRECATED_ERR_TIMING_IPC_FROM_SUBFRAME, |
| 157 | 158 |
| 158 // A timing IPC was sent from the renderer that contained timing data which | 159 // A timing IPC was sent from the renderer that contained timing data which |
| 159 // was inconsistent with our timing data for the currently committed load. | 160 // was inconsistent with our timing data for the currently committed load. |
| 160 ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT, | 161 ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT, |
| 161 | 162 |
| 162 // A timing IPC was sent from the renderer that contained loading behavior | 163 // A timing IPC was sent from the renderer that contained loading behavior |
| 163 // data which was inconsistent with our loading behavior data for the | 164 // data which was inconsistent with our loading behavior data for the |
| 164 // currently committed load. | 165 // currently committed load. |
| 165 ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT, | 166 ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT, |
| 166 | 167 |
| 167 // A timing IPC was sent from the renderer that contained invalid timing data | 168 // A timing IPC was sent from the renderer that contained invalid timing data |
| 168 // (e.g. out of order timings, or other issues). | 169 // (e.g. out of order timings, or other issues). |
| 169 ERR_BAD_TIMING_IPC_INVALID_TIMING, | 170 ERR_BAD_TIMING_IPC_INVALID_TIMING, |
| 170 | 171 |
| 172 // We received an IPC for a subframe when we weren't tracking a committed load | |
| 173 // in that frame. This can happen if the frame fails to commit but a document | |
| 174 // is created in it from the parent document via document.open(). | |
| 175 ERR_SUBFRAME_IPC_WITH_NO_RELEVANT_LOAD, | |
| 176 | |
| 177 // We received a navigation start for a child frame that is before the | |
| 178 // navigation start of the main frame. | |
| 179 ERR_SUBFRAME_NAVIGATION_START_BEFORE_MAIN_FRAME, | |
| 180 | |
| 171 // Add values before this final count. | 181 // Add values before this final count. |
| 172 ERR_LAST_ENTRY, | 182 ERR_LAST_ENTRY, |
| 173 }; | 183 }; |
| 174 | 184 |
| 175 // NOTE: these functions are shared by page_load_tracker.cc and | 185 // NOTE: these functions are shared by page_load_tracker.cc and |
| 176 // metrics_web_contents_observer.cc. They are declared here to allow both files | 186 // metrics_web_contents_observer.cc. They are declared here to allow both files |
| 177 // to access them. | 187 // to access them. |
| 178 void RecordInternalError(InternalErrorLoadEvent event); | 188 void RecordInternalError(InternalErrorLoadEvent event); |
| 179 PageEndReason EndReasonForPageTransition(ui::PageTransition transition); | 189 PageEndReason EndReasonForPageTransition(ui::PageTransition transition); |
| 180 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); | 190 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); |
| 181 bool IsNavigationUserInitiated(content::NavigationHandle* handle); | 191 bool IsNavigationUserInitiated(content::NavigationHandle* handle); |
| 192 content::RenderFrameHost* GetMainFrame(content::RenderFrameHost* rfh); | |
| 182 | 193 |
| 183 // This class tracks a given page load, starting from navigation start / | 194 // This class tracks a given page load, starting from navigation start / |
| 184 // provisional load, until a new navigation commits or the navigation fails. | 195 // provisional load, until a new navigation commits or the navigation fails. |
| 185 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as | 196 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as |
| 186 // well as a committed PageLoadTracker. | 197 // well as a committed PageLoadTracker. |
| 187 class PageLoadTracker { | 198 class PageLoadTracker { |
| 188 public: | 199 public: |
| 189 // Caller must guarantee that the embedder_interface pointer outlives this | 200 // Caller must guarantee that the embedder_interface pointer outlives this |
| 190 // class. The PageLoadTracker must not hold on to | 201 // class. The PageLoadTracker must not hold on to |
| 191 // currently_committed_load_or_null or navigation_handle beyond the scope of | 202 // currently_committed_load_or_null or navigation_handle beyond the scope of |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 215 // metrics as the application goes into the background. The application may be | 226 // metrics as the application goes into the background. The application may be |
| 216 // killed at any time after this method is invoked without further | 227 // killed at any time after this method is invoked without further |
| 217 // notification. | 228 // notification. |
| 218 void FlushMetricsOnAppEnterBackground(); | 229 void FlushMetricsOnAppEnterBackground(); |
| 219 | 230 |
| 220 void NotifyClientRedirectTo(const PageLoadTracker& destination); | 231 void NotifyClientRedirectTo(const PageLoadTracker& destination); |
| 221 | 232 |
| 222 void UpdateTiming(const PageLoadTiming& timing, | 233 void UpdateTiming(const PageLoadTiming& timing, |
| 223 const PageLoadMetadata& metadata); | 234 const PageLoadMetadata& metadata); |
| 224 | 235 |
| 236 void UpdateSubFrameTiming(content::RenderFrameHost* render_frame_host, | |
| 237 const PageLoadTiming& new_timing, | |
| 238 const PageLoadMetadata& new_metadata); | |
| 239 | |
| 225 // Update metadata for child frames. Updates for child frames arrive | 240 // Update metadata for child frames. Updates for child frames arrive |
| 226 // separately from updates for the main frame, so aren't included in | 241 // separately from updates for the main frame, so aren't included in |
| 227 // UpdateTiming. | 242 // UpdateTiming. |
| 228 void UpdateChildFrameMetadata(const PageLoadMetadata& child_metadata); | 243 void UpdateSubFrameMetadata(const PageLoadMetadata& child_metadata); |
|
jkarlin
2017/05/10 16:55:28
Why the rename? Should the comments and argument s
Bryan McQuade
2017/05/10 18:06:15
I wanted to mirror your naming for the subframe co
| |
| 229 | 244 |
| 230 void OnStartedResource( | 245 void OnStartedResource( |
| 231 const ExtraRequestStartInfo& extra_request_started_info); | 246 const ExtraRequestStartInfo& extra_request_started_info); |
| 232 | 247 |
| 233 void OnLoadedResource( | 248 void OnLoadedResource( |
| 234 const ExtraRequestCompleteInfo& extra_request_complete_info); | 249 const ExtraRequestCompleteInfo& extra_request_complete_info); |
| 235 | 250 |
| 236 // Signals that we should stop tracking metrics for the associated page load. | 251 // Signals that we should stop tracking metrics for the associated page load. |
| 237 // We may stop tracking a page load if it doesn't meet the criteria for | 252 // We may stop tracking a page load if it doesn't meet the criteria for |
| 238 // tracking metrics in DidFinishNavigation. | 253 // tracking metrics in DidFinishNavigation. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 const content::WebContentsObserver::MediaPlayerInfo& video_type, | 314 const content::WebContentsObserver::MediaPlayerInfo& video_type, |
| 300 bool is_in_main_frame); | 315 bool is_in_main_frame); |
| 301 | 316 |
| 302 // Invoked on navigations where a navigation delay was added by the | 317 // Invoked on navigations where a navigation delay was added by the |
| 303 // DelayNavigationThrottle. This is a temporary method that will be removed | 318 // DelayNavigationThrottle. This is a temporary method that will be removed |
| 304 // once the experiment is complete. | 319 // once the experiment is complete. |
| 305 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay, | 320 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay, |
| 306 base::TimeDelta actual_delay); | 321 base::TimeDelta actual_delay); |
| 307 | 322 |
| 308 private: | 323 private: |
| 324 using FrameTreeNodeId = int; | |
| 325 | |
| 309 // This function converts a TimeTicks value taken in the browser process | 326 // This function converts a TimeTicks value taken in the browser process |
| 310 // to navigation_start_ if: | 327 // to navigation_start_ if: |
| 311 // - base::TimeTicks is not comparable across processes because the clock | 328 // - base::TimeTicks is not comparable across processes because the clock |
| 312 // is not system wide monotonic. | 329 // is not system wide monotonic. |
| 313 // - *event_time < navigation_start_ | 330 // - *event_time < navigation_start_ |
| 314 void ClampBrowserTimestampIfInterProcessTimeTickSkew( | 331 void ClampBrowserTimestampIfInterProcessTimeTickSkew( |
| 315 base::TimeTicks* event_time); | 332 base::TimeTicks* event_time); |
| 316 | 333 |
| 317 void UpdatePageEndInternal(PageEndReason page_end_reason, | 334 void UpdatePageEndInternal(PageEndReason page_end_reason, |
| 318 UserInitiatedInfo user_initiated_info, | 335 UserInitiatedInfo user_initiated_info, |
| 319 base::TimeTicks timestamp, | 336 base::TimeTicks timestamp, |
| 320 bool is_certainly_browser_timestamp); | 337 bool is_certainly_browser_timestamp); |
| 321 | 338 |
| 322 // If |final_navigation| is null, then this is an "unparented" abort chain, | 339 // If |final_navigation| is null, then this is an "unparented" abort chain, |
| 323 // and represents a sequence of provisional aborts that never ends with a | 340 // and represents a sequence of provisional aborts that never ends with a |
| 324 // committed load. | 341 // committed load. |
| 325 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); | 342 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); |
| 326 | 343 |
| 327 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); | 344 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); |
| 328 | 345 |
| 346 // Merge values from |new_paint_timing| into |merged_page_timing_|, offsetting | |
| 347 // any new timings by the |navigation_start_offset|. | |
| 348 void MergePaintTiming(base::TimeDelta navigation_start_offset, | |
| 349 const page_load_metrics::PaintTiming& new_paint_timing, | |
| 350 bool is_main_frame); | |
| 351 | |
| 329 UserInputTracker input_tracker_; | 352 UserInputTracker input_tracker_; |
| 330 | 353 |
| 331 // Whether we stopped tracking this navigation after it was initiated. We may | 354 // Whether we stopped tracking this navigation after it was initiated. We may |
| 332 // stop tracking a navigation if it doesn't meet the criteria for tracking | 355 // stop tracking a navigation if it doesn't meet the criteria for tracking |
| 333 // metrics in DidFinishNavigation. | 356 // metrics in DidFinishNavigation. |
| 334 bool did_stop_tracking_; | 357 bool did_stop_tracking_; |
| 335 | 358 |
| 336 // Whether the application went into the background when this PageLoadTracker | 359 // Whether the application went into the background when this PageLoadTracker |
| 337 // was active. This is a temporary boolean for UMA tracking. | 360 // was active. This is a temporary boolean for UMA tracking. |
| 338 bool app_entered_background_; | 361 bool app_entered_background_; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 368 | 391 |
| 369 base::TimeTicks page_end_time_; | 392 base::TimeTicks page_end_time_; |
| 370 | 393 |
| 371 // We record separate metrics for events that occur after a background, | 394 // We record separate metrics for events that occur after a background, |
| 372 // because metrics like layout/paint are delayed artificially | 395 // because metrics like layout/paint are delayed artificially |
| 373 // when they occur in the background. | 396 // when they occur in the background. |
| 374 base::TimeTicks background_time_; | 397 base::TimeTicks background_time_; |
| 375 base::TimeTicks foreground_time_; | 398 base::TimeTicks foreground_time_; |
| 376 bool started_in_foreground_; | 399 bool started_in_foreground_; |
| 377 | 400 |
| 378 PageLoadTiming timing_; | 401 // PageLoadTiming for the currently tracked page. The fields in |paint_timing| |
| 402 // are merged across all frames in the document. All other fields are for the | |
| 403 // main frame document. | |
| 404 PageLoadTiming merged_page_timing_; | |
| 405 | |
| 379 PageLoadMetadata main_frame_metadata_; | 406 PageLoadMetadata main_frame_metadata_; |
| 380 PageLoadMetadata child_frame_metadata_; | 407 PageLoadMetadata child_frame_metadata_; |
| 381 | 408 |
| 382 ui::PageTransition page_transition_; | 409 ui::PageTransition page_transition_; |
| 383 | 410 |
| 384 base::Optional<content::GlobalRequestID> navigation_request_id_; | 411 base::Optional<content::GlobalRequestID> navigation_request_id_; |
| 385 | 412 |
| 386 // Whether this page load was user initiated. | 413 // Whether this page load was user initiated. |
| 387 UserInitiatedInfo user_initiated_info_; | 414 UserInitiatedInfo user_initiated_info_; |
| 388 | 415 |
| 389 // This is a subtle member. If a provisional load A gets aborted by | 416 // This is a subtle member. If a provisional load A gets aborted by |
| 390 // provisional load B, which gets aborted by C that eventually commits, then | 417 // provisional load B, which gets aborted by C that eventually commits, then |
| 391 // there exists an abort chain of length 2, starting at A's navigation_start. | 418 // there exists an abort chain of length 2, starting at A's navigation_start. |
| 392 // This is useful because it allows histograming abort chain lengths based on | 419 // This is useful because it allows histograming abort chain lengths based on |
| 393 // what the last load's transition type is. i.e. holding down F-5 to spam | 420 // what the last load's transition type is. i.e. holding down F-5 to spam |
| 394 // reload will produce a long chain with the RELOAD transition. | 421 // reload will produce a long chain with the RELOAD transition. |
| 395 const int aborted_chain_size_; | 422 const int aborted_chain_size_; |
| 396 | 423 |
| 397 // This member counts consecutive provisional aborts that share a url. It will | 424 // This member counts consecutive provisional aborts that share a url. It will |
| 398 // always be less than or equal to |aborted_chain_size_|. | 425 // always be less than or equal to |aborted_chain_size_|. |
| 399 const int aborted_chain_size_same_url_; | 426 const int aborted_chain_size_same_url_; |
| 400 | 427 |
| 401 // Interface to chrome features. Must outlive the class. | 428 // Interface to chrome features. Must outlive the class. |
| 402 PageLoadMetricsEmbedderInterface* const embedder_interface_; | 429 PageLoadMetricsEmbedderInterface* const embedder_interface_; |
| 403 | 430 |
| 404 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; | 431 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; |
| 405 | 432 |
| 433 // Navigation start offsets for the most recently committed document in each | |
| 434 // frame. | |
| 435 std::map<FrameTreeNodeId, base::TimeDelta> | |
| 436 child_frame_navigation_start_offset_; | |
| 437 | |
| 406 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); | 438 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); |
| 407 }; | 439 }; |
| 408 | 440 |
| 409 } // namespace page_load_metrics | 441 } // namespace page_load_metrics |
| 410 | 442 |
| 411 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ | 443 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ |
| OLD | NEW |