 Chromium Code Reviews
 Chromium Code Reviews Issue 1449253002:
  [do not review][page_load_metrics] User Initiated Abort Tracking  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@plm_navigation_start
    
  
    Issue 1449253002:
  [do not review][page_load_metrics] User Initiated Abort Tracking  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@plm_navigation_start| OLD | NEW | 
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSE RVER_H_ | 5 #ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSE RVER_H_ | 
| 6 #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSE RVER_H_ | 6 #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSE RVER_H_ | 
| 7 | 7 | 
| 8 #include "base/containers/scoped_ptr_map.h" | 8 #include "base/containers/scoped_ptr_map.h" | 
| 9 #include "base/macros.h" | 9 #include "base/macros.h" | 
| 10 #include "base/memory/scoped_vector.h" | |
| 10 #include "base/observer_list.h" | 11 #include "base/observer_list.h" | 
| 11 #include "base/time/time.h" | 12 #include "base/time/time.h" | 
| 12 #include "components/page_load_metrics/browser/page_load_metrics_observer.h" | 13 #include "components/page_load_metrics/browser/page_load_metrics_observer.h" | 
| 13 #include "components/page_load_metrics/common/page_load_timing.h" | 14 #include "components/page_load_metrics/common/page_load_timing.h" | 
| 14 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" | 
| 15 #include "content/public/browser/web_contents_observer.h" | 16 #include "content/public/browser/web_contents_observer.h" | 
| 16 #include "content/public/browser/web_contents_user_data.h" | 17 #include "content/public/browser/web_contents_user_data.h" | 
| 17 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" | 
| 18 | 19 | 
| 19 class PageLoadMetricsObserverTest; | 20 class PageLoadMetricsObserverTest; | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 | 68 | 
| 68 const char kProvisionalEvents[] = "PageLoad.Events.Provisional"; | 69 const char kProvisionalEvents[] = "PageLoad.Events.Provisional"; | 
| 69 const char kCommittedEvents[] = "PageLoad.Events.Committed"; | 70 const char kCommittedEvents[] = "PageLoad.Events.Committed"; | 
| 70 const char kBackgroundProvisionalEvents[] = | 71 const char kBackgroundProvisionalEvents[] = | 
| 71 "PageLoad.Events.Provisional.Background"; | 72 "PageLoad.Events.Provisional.Background"; | 
| 72 const char kBackgroundCommittedEvents[] = | 73 const char kBackgroundCommittedEvents[] = | 
| 73 "PageLoad.Events.Committed.Background"; | 74 "PageLoad.Events.Committed.Background"; | 
| 74 | 75 | 
| 75 const char kErrorEvents[] = "PageLoad.Events.InternalError"; | 76 const char kErrorEvents[] = "PageLoad.Events.InternalError"; | 
| 76 | 77 | 
| 78 const char kHistogramProvisionalAbortForwardBack[] = | |
| 79 "PageLoad.Timing2.Aborts.Provisional.ForwardBackBeforeFirstPaint"; | |
| 
Bryan McQuade
2015/11/17 13:33:08
do you think the provisional vs committed distinct
 
Bryan McQuade
2015/11/17 13:33:08
can we use 'BeforePaint' rather than 'BeforeFirstP
 
Bryan McQuade
2015/11/17 13:33:08
nit: let's stick to singular rather than pluran in
 
Charlie Harrison
2015/11/17 16:11:54
Done. (Aborts => Abort)
 
Charlie Harrison
2015/11/17 16:11:55
Done. (BeforePaint)
 
Charlie Harrison
2015/11/17 16:11:55
Yeah the distinction is not great, but there are t
 | |
| 80 const char kHistogramProvisionalAbortReload[] = | |
| 81 "PageLoad.Timing2.Aborts.Provisional.ReloadBeforeFirstPaint"; | |
| 82 const char kHistogramProvisionalAbortNewNavigation[] = | |
| 83 "PageLoad.Timing2.Aborts.Provisional.NewNavigationBeforeFirstPaint"; | |
| 84 const char kHistogramProvisionalAbortStop[] = | |
| 85 "PageLoad.Timing2.Aborts.Provisional.StopBeforeFirstPaint"; | |
| 86 const char kHistogramProvisionalAbortClose[] = | |
| 87 "PageLoad.Timing2.Aborts.Provisional.CloseBeforeFirstPaint"; | |
| 88 const char kHistogramProvisionalAbortOther[] = | |
| 89 "PageLoad.Timing2.Aborts.Provisional.OtherAbortBeforeFirstPaint"; | |
| 90 const char kHistogramProvisionalAbortBackground[] = | |
| 91 "PageLoad.Timing2.Aborts.Provisional.BackgroundBeforeFirstPaint"; | |
| 92 const char kHistogramCommittedAbortForwardBack[] = | |
| 93 "PageLoad.Timing2.Aborts.Committed.ForwardBackBeforeFirstPaint"; | |
| 94 const char kHistogramCommittedAbortReload[] = | |
| 95 "PageLoad.Timing2.Aborts.Committed.ReloadBeforeFirstPaint"; | |
| 96 const char kHistogramCommittedAbortNewNavigation[] = | |
| 97 "PageLoad.Timing2.Aborts.Committed.NewNavigationBeforeFirstPaint"; | |
| 98 const char kHistogramCommittedAbortStop[] = | |
| 99 "PageLoad.Timing2.Aborts.Committed.StopBeforeFirstPaint"; | |
| 100 const char kHistogramCommittedAbortClose[] = | |
| 101 "PageLoad.Timing2.Aborts.Committed.CloseBeforeFirstPaint"; | |
| 102 const char kHistogramCommittedAbortOther[] = | |
| 103 "PageLoad.Timing2.Aborts.Committed.OtherAbortBeforeFirstPaint"; | |
| 104 const char kHistogramCommittedAbortBackground[] = | |
| 105 "PageLoad.Timing2.Aborts.Committed.BackgroundBeforeFirstPaint"; | |
| 106 | |
| 77 const char kRapporMetricsNameCoarseTiming[] = | 107 const char kRapporMetricsNameCoarseTiming[] = | 
| 78 "PageLoad.CoarseTiming.NavigationToFirstContentfulPaint"; | 108 "PageLoad.CoarseTiming.NavigationToFirstContentfulPaint"; | 
| 79 | 109 | 
| 80 // NOTE: Some of these histograms are separated into a separate histogram | 110 // NOTE: Some of these histograms are separated into a separate histogram | 
| 81 // specified by the ".Background" suffix. For these events, we put them into the | 111 // specified by the ".Background" suffix. For these events, we put them into the | 
| 82 // background histogram if the web contents was ever in the background from | 112 // background histogram if the web contents was ever in the background from | 
| 83 // navigation start to the event in question. | 113 // navigation start to the event in question. | 
| 84 | 114 | 
| 85 // ProvisionalLoadEvents count all main frame navigations before they commit. | 115 // ProvisionalLoadEvents count all main frame navigations before they commit. | 
| 86 // The events in this enum are all disjoint, and summing them yields the total | 116 // The events in this enum are all disjoint, and summing them yields the total | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 ERR_IPC_FROM_BAD_URL_SCHEME, | 198 ERR_IPC_FROM_BAD_URL_SCHEME, | 
| 169 | 199 | 
| 170 // If we track a navigation, but the renderer sends us no IPCs. This could | 200 // If we track a navigation, but the renderer sends us no IPCs. This could | 
| 171 // occur if the browser filters loads less aggressively than the renderer. | 201 // occur if the browser filters loads less aggressively than the renderer. | 
| 172 ERR_NO_IPCS_RECEIVED, | 202 ERR_NO_IPCS_RECEIVED, | 
| 173 | 203 | 
| 174 // Add values before this final count. | 204 // Add values before this final count. | 
| 175 ERR_LAST_ENTRY | 205 ERR_LAST_ENTRY | 
| 176 }; | 206 }; | 
| 177 | 207 | 
| 208 // This enum represents how a page load ends. If the action occurs before the | |
| 209 // page load finishes (or reaches some point like first paint), then we consider | |
| 210 // the load to be aborted. | |
| 211 enum UserAbortType { | |
| 212 // Represents no abort. | |
| 213 ABORT_NULL, | |
| 
Bryan McQuade
2015/11/17 13:33:08
most enums I see use a _NONE suffix for this, rath
 
Charlie Harrison
2015/11/17 16:11:54
Done.
 | |
| 214 | |
| 215 // If the user presses reload or shift-reload. | |
| 216 ABORT_RELOAD, | |
| 217 | |
| 218 // The user presses the back/forward button. | |
| 219 ABORT_FORWARD_BACK, | |
| 220 | |
| 221 // If the navigation is replaced by a new navigation. This includes link | |
| 222 // clicks, typing in the omnibox (not a reload), and form submissions. | |
| 223 ABORT_NEW_NAVIGATION, | |
| 224 | |
| 225 // If the user presses the stop X button. | |
| 226 ABORT_STOP, | |
| 227 | |
| 228 // If the navigation is aborted by closing the tab or browser. | |
| 229 ABORT_CLOSE, | |
| 230 | |
| 231 // We don't know why the navigation aborted. This is the value we assign to an | |
| 232 // aborted load if the only signal we get is a provisional load finishing | |
| 233 // without committing, either without error or with net::ERR_ABORTED. | |
| 234 ABORT_OTHER, | |
| 235 | |
| 236 // Add values before this final count. | |
| 237 ABORT_LAST_ENTRY | |
| 238 }; | |
| 239 | |
| 178 // This class serves as a functional interface to various chrome// features. | 240 // This class serves as a functional interface to various chrome// features. | 
| 179 // Impl version is defined in chrome/browser/page_load_metrics. | 241 // Impl version is defined in chrome/browser/page_load_metrics. | 
| 180 class PageLoadMetricsEmbedderInterface { | 242 class PageLoadMetricsEmbedderInterface { | 
| 181 public: | 243 public: | 
| 182 virtual ~PageLoadMetricsEmbedderInterface() {} | 244 virtual ~PageLoadMetricsEmbedderInterface() {} | 
| 183 virtual rappor::RapporService* GetRapporService() = 0; | 245 virtual rappor::RapporService* GetRapporService() = 0; | 
| 184 virtual bool IsPrerendering(content::WebContents* web_contents) = 0; | 246 virtual bool IsPrerendering(content::WebContents* web_contents) = 0; | 
| 185 }; | 247 }; | 
| 186 | 248 | 
| 187 // This class tracks a given page load, starting from navigation start / | 249 // This class tracks a given page load, starting from navigation start / | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 201 void Commit(content::NavigationHandle* navigation_handle); | 263 void Commit(content::NavigationHandle* navigation_handle); | 
| 202 void WebContentsHidden(); | 264 void WebContentsHidden(); | 
| 203 void WebContentsShown(); | 265 void WebContentsShown(); | 
| 204 | 266 | 
| 205 // Returns true if the timing was successfully updated. | 267 // Returns true if the timing was successfully updated. | 
| 206 bool UpdateTiming(const PageLoadTiming& timing); | 268 bool UpdateTiming(const PageLoadTiming& timing); | 
| 207 void RecordProvisionalEvent(ProvisionalLoadEvent event); | 269 void RecordProvisionalEvent(ProvisionalLoadEvent event); | 
| 208 void RecordCommittedEvent(CommittedLoadEvent event, bool backgrounded); | 270 void RecordCommittedEvent(CommittedLoadEvent event, bool backgrounded); | 
| 209 bool HasBackgrounded(); | 271 bool HasBackgrounded(); | 
| 210 | 272 | 
| 273 // If the user performs some abort-like action while we are tracking this page | |
| 274 // load, notify the tracker. Note that we may not classify this as an abort if | |
| 275 // we've already performed a first paint. | |
| 276 void NotifyAbort(UserAbortType abort_type, const base::TimeTicks& timestamp); | |
| 277 | |
| 211 private: | 278 private: | 
| 212 PageLoadExtraInfo GetPageLoadMetricsInfo(); | 279 PageLoadExtraInfo GetPageLoadMetricsInfo(); | 
| 213 // Only valid to call post-commit. | 280 // Only valid to call post-commit. | 
| 214 const GURL& GetCommittedURL(); | 281 const GURL& GetCommittedURL(); | 
| 215 | 282 | 
| 216 base::TimeDelta GetBackgroundDelta(); | 283 base::TimeDelta GetBackgroundDelta(); | 
| 217 void RecordTimingHistograms(); | 284 void RecordTimingHistograms(); | 
| 285 void RecordAbortTimingHistograms(); | |
| 218 void RecordRappor(); | 286 void RecordRappor(); | 
| 219 | 287 | 
| 220 bool has_commit_; | 288 bool has_commit_; | 
| 221 | 289 | 
| 222 // The navigation start in TimeTicks, not the wall time reported by Blink. | 290 // The navigation start in TimeTicks, not the wall time reported by Blink. | 
| 223 const base::TimeTicks navigation_start_; | 291 const base::TimeTicks navigation_start_; | 
| 224 | 292 | 
| 293 // Will be ABORT_NULL if we have not aborted this load yet. Otherwise will | |
| 294 // be the first abort action the user performed. | |
| 295 UserAbortType abort_type_; | |
| 296 base::TimeTicks abort_time_; | |
| 297 | |
| 225 // We record separate metrics for events that occur after a background, | 298 // We record separate metrics for events that occur after a background, | 
| 226 // because metrics like layout/paint are delayed artificially | 299 // because metrics like layout/paint are delayed artificially | 
| 227 // when they occur in the background. | 300 // when they occur in the background. | 
| 228 base::TimeTicks background_time_; | 301 base::TimeTicks background_time_; | 
| 229 base::TimeTicks foreground_time_; | 302 base::TimeTicks foreground_time_; | 
| 230 bool started_in_foreground_; | 303 bool started_in_foreground_; | 
| 231 | 304 | 
| 232 PageLoadTiming timing_; | 305 PageLoadTiming timing_; | 
| 233 GURL url_; | 306 GURL url_; | 
| 234 | 307 | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 262 void AddObserver(PageLoadMetricsObserver* observer) override; | 335 void AddObserver(PageLoadMetricsObserver* observer) override; | 
| 263 void RemoveObserver(PageLoadMetricsObserver* observer) override; | 336 void RemoveObserver(PageLoadMetricsObserver* observer) override; | 
| 264 | 337 | 
| 265 // content::WebContentsObserver implementation: | 338 // content::WebContentsObserver implementation: | 
| 266 bool OnMessageReceived(const IPC::Message& message, | 339 bool OnMessageReceived(const IPC::Message& message, | 
| 267 content::RenderFrameHost* render_frame_host) override; | 340 content::RenderFrameHost* render_frame_host) override; | 
| 268 void DidStartNavigation( | 341 void DidStartNavigation( | 
| 269 content::NavigationHandle* navigation_handle) override; | 342 content::NavigationHandle* navigation_handle) override; | 
| 270 void DidFinishNavigation( | 343 void DidFinishNavigation( | 
| 271 content::NavigationHandle* navigation_handle) override; | 344 content::NavigationHandle* navigation_handle) override; | 
| 272 | 345 void NavigationStopped() override; | 
| 273 void WasShown() override; | 346 void WasShown() override; | 
| 274 void WasHidden() override; | 347 void WasHidden() override; | 
| 275 | |
| 276 void RenderProcessGone(base::TerminationStatus status) override; | 348 void RenderProcessGone(base::TerminationStatus status) override; | 
| 277 | 349 | 
| 278 private: | 350 private: | 
| 279 friend class content::WebContentsUserData<MetricsWebContentsObserver>; | 351 friend class content::WebContentsUserData<MetricsWebContentsObserver>; | 
| 280 | 352 | 
| 353 // Notify all loads, provisional and committed, that we performed an action | |
| 354 // that might abort them. | |
| 355 void NotifyAbortAllLoads(UserAbortType abort_type); | |
| 356 void NotifyAbortAllLoadsWithTimestamp(UserAbortType abort_type, | |
| 357 const base::TimeTicks& timestamp); | |
| 358 | |
| 281 void OnTimingUpdated(content::RenderFrameHost*, const PageLoadTiming& timing); | 359 void OnTimingUpdated(content::RenderFrameHost*, const PageLoadTiming& timing); | 
| 282 | 360 | 
| 283 // True if the web contents is currently in the foreground. | 361 // True if the web contents is currently in the foreground. | 
| 284 bool in_foreground_; | 362 bool in_foreground_; | 
| 285 | 363 | 
| 286 // This map tracks all of the navigations ongoing that are not committed | 364 // This map tracks all of the navigations ongoing that are not committed | 
| 287 // yet. Once a navigation is committed, it moves from the map to | 365 // yet. Once a navigation is committed, it moves from the map to | 
| 288 // committed_load_. Note that a PageLoadTrackers NavigationHandle is only | 366 // committed_load_. Note that a PageLoadTrackers NavigationHandle is only | 
| 289 // valid until commit time, when we remove it from the map. | 367 // valid until commit time, when we remove it from the map. | 
| 290 base::ScopedPtrMap<content::NavigationHandle*, scoped_ptr<PageLoadTracker>> | 368 base::ScopedPtrMap<content::NavigationHandle*, scoped_ptr<PageLoadTracker>> | 
| 291 provisional_loads_; | 369 provisional_loads_; | 
| 370 // Tracks aborted provisional loads for a little bit longer than usual (one | |
| 371 // more navigation commit at the max), in order to better understand how the | |
| 372 // navigation failed. This is because most provisional loads are destroyed and | |
| 373 // vanish before we get signal about what caused the abort (new navigation, | |
| 374 // stop button, etc.). | |
| 375 ScopedVector<PageLoadTracker> aborted_provisional_loads_; | |
| 292 scoped_ptr<PageLoadTracker> committed_load_; | 376 scoped_ptr<PageLoadTracker> committed_load_; | 
| 293 | 377 | 
| 294 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface_; | 378 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface_; | 
| 295 base::ObserverList<PageLoadMetricsObserver, true> observers_; | 379 base::ObserverList<PageLoadMetricsObserver, true> observers_; | 
| 296 | 380 | 
| 297 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserver); | 381 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserver); | 
| 298 }; | 382 }; | 
| 299 | 383 | 
| 300 } // namespace page_load_metrics | 384 } // namespace page_load_metrics | 
| 301 | 385 | 
| 302 #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_O BSERVER_H_ | 386 #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_O BSERVER_H_ | 
| OLD | NEW |