| 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 <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 namespace IPC { | 27 namespace IPC { |
| 28 class Message; | 28 class Message; |
| 29 } // namespace IPC | 29 } // namespace IPC |
| 30 | 30 |
| 31 namespace rappor { | 31 namespace rappor { |
| 32 class RapporService; | 32 class RapporService; |
| 33 } | 33 } |
| 34 | 34 |
| 35 namespace page_load_metrics { | 35 namespace page_load_metrics { |
| 36 | 36 |
| 37 class PageLoadTracker; |
| 38 |
| 37 // These constants are for keeping the tests in sync. | 39 // These constants are for keeping the tests in sync. |
| 38 const char kHistogramFirstLayout[] = "PageLoad.Timing2.NavigationToFirstLayout"; | 40 const char kHistogramFirstLayout[] = "PageLoad.Timing2.NavigationToFirstLayout"; |
| 39 const char kHistogramFirstTextPaint[] = | 41 const char kHistogramFirstTextPaint[] = |
| 40 "PageLoad.Timing2.NavigationToFirstTextPaint"; | 42 "PageLoad.Timing2.NavigationToFirstTextPaint"; |
| 41 const char kHistogramDomContentLoaded[] = | 43 const char kHistogramDomContentLoaded[] = |
| 42 "PageLoad.Timing2.NavigationToDOMContentLoadedEventFired"; | 44 "PageLoad.Timing2.NavigationToDOMContentLoadedEventFired"; |
| 43 const char kHistogramLoad[] = "PageLoad.Timing2.NavigationToLoadEventFired"; | 45 const char kHistogramLoad[] = "PageLoad.Timing2.NavigationToLoadEventFired"; |
| 44 const char kHistogramFirstPaint[] = "PageLoad.Timing2.NavigationToFirstPaint"; | 46 const char kHistogramFirstPaint[] = "PageLoad.Timing2.NavigationToFirstPaint"; |
| 45 const char kHistogramFirstImagePaint[] = | 47 const char kHistogramFirstImagePaint[] = |
| 46 "PageLoad.Timing2.NavigationToFirstImagePaint"; | 48 "PageLoad.Timing2.NavigationToFirstImagePaint"; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 // This event captures all the other ways a provisional load can fail. | 112 // This event captures all the other ways a provisional load can fail. |
| 111 PROVISIONAL_LOAD_ERR_FAILED_NON_ABORT, | 113 PROVISIONAL_LOAD_ERR_FAILED_NON_ABORT, |
| 112 | 114 |
| 113 // Counts the number of successful commits. | 115 // Counts the number of successful commits. |
| 114 PROVISIONAL_LOAD_COMMITTED, | 116 PROVISIONAL_LOAD_COMMITTED, |
| 115 | 117 |
| 116 // Add values before this final count. | 118 // Add values before this final count. |
| 117 PROVISIONAL_LOAD_LAST_ENTRY | 119 PROVISIONAL_LOAD_LAST_ENTRY |
| 118 }; | 120 }; |
| 119 | 121 |
| 120 // CommittedLoadEvents are events that occur on committed loads that we track. | 122 // CommittedRelevantLoadEvents are events that occur on committed loads that the |
| 121 // Note that we capture events only for committed loads that: | 123 // MetricsWebContentsObserver tracks. Note events are only captured for |
| 124 // committed loads that: |
| 122 // - Are http/https. | 125 // - Are http/https. |
| 123 // - Not same-page navigations. | 126 // - Not same-page navigations. |
| 124 // - Are not navigations to an error page. | 127 // - Are not navigations to an error page. |
| 125 // We only know these things about a navigation post-commit. | 128 // We only know these things about a navigation post-commit. |
| 126 // | 129 // |
| 127 // If you add elements to this enum, make sure you update the enum | 130 // If you add elements to this enum, make sure you update the enum |
| 128 // value in histograms.xml. Only add elements to the end to prevent | 131 // value in histograms.xml. Only add elements to the end to prevent |
| 129 // inconsistencies between versions. | 132 // inconsistencies between versions. |
| 130 enum CommittedLoadEvent { | 133 enum CommittedRelevantLoadEvent { |
| 131 // When a load that eventually commits started. Note we can't log this until | 134 // When a load that eventually commits started. This cannot be logged until |
| 132 // commit time, but it represents when the actual page load started. Thus, we | 135 // commit time, but it represents when the actual page load started. Thus, it |
| 133 // only separate this into .Background when a page load starts backgrounded. | 136 // only separates into .Background when a page load starts backgrounded. |
| 134 COMMITTED_LOAD_STARTED, | 137 RELEVANT_LOAD_STARTED, |
| 135 | 138 |
| 136 // These two events are disjoint. Sum them to find the total number of | 139 // These two events are disjoint. Sum them to find the total number of |
| 137 // committed loads that we end up tracking. | 140 // committed loads that are tracked. |
| 138 COMMITTED_LOAD_FAILED_BEFORE_FIRST_LAYOUT, | 141 RELEVANT_LOAD_FAILED_BEFORE_FIRST_LAYOUT, |
| 139 COMMITTED_LOAD_SUCCESSFUL_FIRST_LAYOUT, | 142 RELEVANT_LOAD_SUCCESSFUL_FIRST_LAYOUT, |
| 140 | 143 |
| 141 // TODO(csharrison) once first paint metrics are in place, add new events. | 144 // TODO(csharrison) once first paint metrics are in place, add new events. |
| 142 | 145 |
| 143 // Add values before this final count. | 146 // Add values before this final count. |
| 144 COMMITTED_LOAD_LAST_ENTRY | 147 RELEVANT_LOAD_LAST_ENTRY |
| 145 }; | 148 }; |
| 146 | 149 |
| 147 // These errors are internal to the page_load_metrics subsystem and do not | 150 // These errors are internal to the page_load_metrics subsystem and do not |
| 148 // reflect actual errors that occur during a page load. | 151 // reflect actual errors that occur during a page load. |
| 149 // | 152 // |
| 150 // If you add elements to this enum, make sure you update the enum | 153 // If you add elements to this enum, make sure you update the enum |
| 151 // value in histograms.xml. Only add elements to the end to prevent | 154 // value in histograms.xml. Only add elements to the end to prevent |
| 152 // inconsistencies between versions. | 155 // inconsistencies between versions. |
| 153 enum InternalErrorLoadEvent { | 156 enum InternalErrorLoadEvent { |
| 154 // A timing IPC was sent from the renderer that did not line up with previous | 157 // A timing IPC was sent from the renderer that did not line up with previous |
| 155 // data we've received (i.e. navigation start is different or the timing | 158 // data we've received (i.e. navigation start is different or the timing |
| 156 // struct is somehow invalid). This error can only occur once the IPC is | 159 // struct is somehow invalid). This error can only occur once the IPC is |
| 157 // vetted in other ways (see other errors). | 160 // vetted in other ways (see other errors). |
| 158 ERR_BAD_TIMING_IPC, | 161 ERR_BAD_TIMING_IPC, |
| 159 | 162 |
| 160 // The following IPCs are not mutually exclusive. | 163 // The following IPCs are not mutually exclusive. |
| 161 // | 164 // |
| 162 // We received an IPC when we weren't tracking a committed load. This will | 165 // We received an IPC when we weren't tracking a committed load. This will |
| 163 // often happen if we get an IPC from a bad URL scheme (that is, the renderer | 166 // often happen if we get an IPC from a bad URL scheme (that is, the renderer |
| 164 // sent us an IPC from a navigation we don't care about). | 167 // sent us an IPC from a navigation we don't care about). |
| 165 ERR_IPC_WITH_NO_COMMITTED_LOAD, | 168 ERR_IPC_WITH_NO_RELEVANT_LOAD, |
| 166 | 169 |
| 167 // Received a notification from a frame that has been navigated away from. | 170 // Received a notification from a frame that has been navigated away from. |
| 168 ERR_IPC_FROM_WRONG_FRAME, | 171 ERR_IPC_FROM_WRONG_FRAME, |
| 169 | 172 |
| 170 // We received an IPC even through the last committed url from the browser | 173 // We received an IPC even through the last committed url from the browser |
| 171 // was not http/s. This can happen with the renderer sending IPCs for the | 174 // was not http/s. This can happen with the renderer sending IPCs for the |
| 172 // new tab page. This will often come paired with | 175 // new tab page. This will often come paired with |
| 173 // ERR_IPC_WITH_NO_COMMITTED_LOAD. | 176 // ERR_IPC_WITH_NO_RELEVANT_LOAD. |
| 174 ERR_IPC_FROM_BAD_URL_SCHEME, | 177 ERR_IPC_FROM_BAD_URL_SCHEME, |
| 175 | 178 |
| 176 // If we track a navigation, but the renderer sends us no IPCs. This could | 179 // If we track a navigation, but the renderer sends us no IPCs. This could |
| 177 // occur if the browser filters loads less aggressively than the renderer. | 180 // occur if the browser filters loads less aggressively than the renderer. |
| 178 ERR_NO_IPCS_RECEIVED, | 181 ERR_NO_IPCS_RECEIVED, |
| 179 | 182 |
| 180 // Add values before this final count. | 183 // Add values before this final count. |
| 181 ERR_LAST_ENTRY | 184 ERR_LAST_ENTRY |
| 182 }; | 185 }; |
| 183 | 186 |
| 184 // This class serves as a functional interface to various chrome// features. | 187 // This class serves as a functional interface to various chrome// features. |
| 185 // Impl version is defined in chrome/browser/page_load_metrics. | 188 // Impl version is defined in chrome/browser/page_load_metrics. |
| 186 class PageLoadMetricsEmbedderInterface { | 189 class PageLoadMetricsEmbedderInterface { |
| 187 public: | 190 public: |
| 188 virtual ~PageLoadMetricsEmbedderInterface() {} | 191 virtual ~PageLoadMetricsEmbedderInterface() {} |
| 189 virtual rappor::RapporService* GetRapporService() = 0; | 192 virtual rappor::RapporService* GetRapporService() = 0; |
| 190 virtual bool IsPrerendering(content::WebContents* web_contents) = 0; | 193 virtual bool IsPrerendering(content::WebContents* web_contents) = 0; |
| 194 virtual void RegisterObservers(PageLoadTracker* metrics) = 0; |
| 191 }; | 195 }; |
| 192 | 196 |
| 193 // This class tracks a given page load, starting from navigation start / | 197 // This class tracks a given page load, starting from navigation start / |
| 194 // provisional load, until a new navigation commits or the navigation fails. It | 198 // provisional load, until a new navigation commits or the navigation fails. It |
| 195 // also records RAPPOR/UMA about the page load. | 199 // also records RAPPOR/UMA about the page load. |
| 196 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as | 200 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as |
| 197 // well as a committed PageLoadTracker. | 201 // well as a committed PageLoadTracker. |
| 198 class PageLoadTracker { | 202 class PageLoadTracker { |
| 199 public: | 203 public: |
| 200 // Caller must guarantee that the observers and embedder_interface pointers | 204 // Caller must guarantee that the embedder_interface pointer outlives this |
| 201 // outlives this class. | 205 // class. |
| 202 PageLoadTracker(bool in_foreground, | 206 PageLoadTracker(bool in_foreground, |
| 203 PageLoadMetricsEmbedderInterface* embedder_interface, | 207 PageLoadMetricsEmbedderInterface* embedder_interface, |
| 204 content::NavigationHandle* navigation_handle, | 208 content::NavigationHandle* navigation_handle); |
| 205 base::ObserverList<PageLoadMetricsObserver, true>* observers); | |
| 206 ~PageLoadTracker(); | 209 ~PageLoadTracker(); |
| 207 void Redirect(content::NavigationHandle* navigation_handle); | 210 void Redirect(content::NavigationHandle* navigation_handle); |
| 208 void Commit(content::NavigationHandle* navigation_handle); | 211 void Commit(content::NavigationHandle* navigation_handle); |
| 209 void WebContentsHidden(); | 212 void WebContentsHidden(); |
| 210 void WebContentsShown(); | 213 void WebContentsShown(); |
| 211 | 214 |
| 212 // Returns true if the timing was successfully updated. | 215 // Returns true if the timing was successfully updated. |
| 213 bool UpdateTiming(const PageLoadTiming& timing); | 216 bool UpdateTiming(const PageLoadTiming& timing); |
| 214 void RecordProvisionalEvent(ProvisionalLoadEvent event); | 217 void RecordProvisionalEvent(ProvisionalLoadEvent event); |
| 215 void RecordCommittedEvent(CommittedLoadEvent event, bool backgrounded); | 218 void RecordCommittedEvent(CommittedRelevantLoadEvent event, |
| 219 bool backgrounded); |
| 216 bool HasBackgrounded(); | 220 bool HasBackgrounded(); |
| 217 | 221 |
| 222 void set_renderer_tracked(bool renderer_tracked); |
| 223 bool renderer_tracked() { return renderer_tracked_; } |
| 224 |
| 225 void AddObserver(scoped_ptr<PageLoadMetricsObserver> observer); |
| 226 |
| 218 private: | 227 private: |
| 219 PageLoadExtraInfo GetPageLoadMetricsInfo(); | 228 PageLoadExtraInfo GetPageLoadMetricsInfo(); |
| 220 // Only valid to call post-commit. | 229 // Only valid to call post-commit. |
| 221 const GURL& GetCommittedURL(); | 230 const GURL& committed_url(); |
| 222 | 231 |
| 223 base::TimeDelta GetBackgroundDelta(); | 232 base::TimeDelta GetBackgroundDelta(); |
| 224 void RecordTimingHistograms(); | 233 void RecordTimingHistograms(); |
| 225 void RecordRappor(); | 234 void RecordRappor(); |
| 226 | 235 |
| 236 // Whether the renderer should be sending timing IPCs to this page load. |
| 237 bool renderer_tracked_; |
| 238 |
| 227 bool has_commit_; | 239 bool has_commit_; |
| 228 | 240 |
| 229 // The navigation start in TimeTicks, not the wall time reported by Blink. | 241 // The navigation start in TimeTicks, not the wall time reported by Blink. |
| 230 const base::TimeTicks navigation_start_; | 242 const base::TimeTicks navigation_start_; |
| 231 | 243 |
| 232 // We record separate metrics for events that occur after a background, | 244 // We record separate metrics for events that occur after a background, |
| 233 // because metrics like layout/paint are delayed artificially | 245 // because metrics like layout/paint are delayed artificially |
| 234 // when they occur in the background. | 246 // when they occur in the background. |
| 235 base::TimeTicks background_time_; | 247 base::TimeTicks background_time_; |
| 236 base::TimeTicks foreground_time_; | 248 base::TimeTicks foreground_time_; |
| 237 bool started_in_foreground_; | 249 bool started_in_foreground_; |
| 238 | 250 |
| 239 PageLoadTiming timing_; | 251 PageLoadTiming timing_; |
| 240 GURL url_; | 252 GURL url_; |
| 241 | 253 |
| 242 // Interface to chrome features. Must outlive the class. | 254 // Interface to chrome features. Must outlive the class. |
| 243 PageLoadMetricsEmbedderInterface* const embedder_interface_; | 255 PageLoadMetricsEmbedderInterface* const embedder_interface_; |
| 244 | 256 |
| 245 // List of observers. This must outlive the class. | 257 std::vector<scoped_ptr<PageLoadMetricsObserver>> observers_; |
| 246 base::ObserverList<PageLoadMetricsObserver, true>* observers_; | |
| 247 | 258 |
| 248 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); | 259 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); |
| 249 }; | 260 }; |
| 250 | 261 |
| 251 // MetricsWebContentsObserver logs page load UMA metrics based on | 262 // MetricsWebContentsObserver logs page load UMA metrics based on |
| 252 // IPC messages received from a MetricsRenderFrameObserver. | 263 // IPC messages received from a MetricsRenderFrameObserver. |
| 253 class MetricsWebContentsObserver | 264 class MetricsWebContentsObserver |
| 254 : public content::WebContentsObserver, | 265 : public content::WebContentsObserver, |
| 255 public content::WebContentsUserData<MetricsWebContentsObserver>, | 266 public content::WebContentsUserData<MetricsWebContentsObserver> { |
| 256 public PageLoadMetricsObservable { | |
| 257 public: | 267 public: |
| 258 // Note that the returned metrics is owned by the web contents. | 268 // Note that the returned metrics is owned by the web contents. |
| 259 // The caller must guarantee that the RapporService (if non-null) will | 269 // The caller must guarantee that the RapporService (if non-null) will |
| 260 // outlive the WebContents. | 270 // outlive the WebContents. |
| 261 static MetricsWebContentsObserver* CreateForWebContents( | 271 static MetricsWebContentsObserver* CreateForWebContents( |
| 262 content::WebContents* web_contents, | 272 content::WebContents* web_contents, |
| 263 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface); | 273 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface); |
| 264 MetricsWebContentsObserver( | 274 MetricsWebContentsObserver( |
| 265 content::WebContents* web_contents, | 275 content::WebContents* web_contents, |
| 266 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface); | 276 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface); |
| 267 ~MetricsWebContentsObserver() override; | 277 ~MetricsWebContentsObserver() override; |
| 268 | 278 |
| 269 void AddObserver(PageLoadMetricsObserver* observer) override; | |
| 270 void RemoveObserver(PageLoadMetricsObserver* observer) override; | |
| 271 | |
| 272 // content::WebContentsObserver implementation: | 279 // content::WebContentsObserver implementation: |
| 273 bool OnMessageReceived(const IPC::Message& message, | 280 bool OnMessageReceived(const IPC::Message& message, |
| 274 content::RenderFrameHost* render_frame_host) override; | 281 content::RenderFrameHost* render_frame_host) override; |
| 275 void DidStartNavigation( | 282 void DidStartNavigation( |
| 276 content::NavigationHandle* navigation_handle) override; | 283 content::NavigationHandle* navigation_handle) override; |
| 277 void DidFinishNavigation( | 284 void DidFinishNavigation( |
| 278 content::NavigationHandle* navigation_handle) override; | 285 content::NavigationHandle* navigation_handle) override; |
| 279 void DidRedirectNavigation( | 286 void DidRedirectNavigation( |
| 280 content::NavigationHandle* navigation_handle) override; | 287 content::NavigationHandle* navigation_handle) override; |
| 281 | 288 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 294 | 301 |
| 295 // This map tracks all of the navigations ongoing that are not committed | 302 // This map tracks all of the navigations ongoing that are not committed |
| 296 // yet. Once a navigation is committed, it moves from the map to | 303 // yet. Once a navigation is committed, it moves from the map to |
| 297 // committed_load_. Note that a PageLoadTrackers NavigationHandle is only | 304 // committed_load_. Note that a PageLoadTrackers NavigationHandle is only |
| 298 // valid until commit time, when we remove it from the map. | 305 // valid until commit time, when we remove it from the map. |
| 299 std::map<content::NavigationHandle*, scoped_ptr<PageLoadTracker>> | 306 std::map<content::NavigationHandle*, scoped_ptr<PageLoadTracker>> |
| 300 provisional_loads_; | 307 provisional_loads_; |
| 301 scoped_ptr<PageLoadTracker> committed_load_; | 308 scoped_ptr<PageLoadTracker> committed_load_; |
| 302 | 309 |
| 303 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface_; | 310 scoped_ptr<PageLoadMetricsEmbedderInterface> embedder_interface_; |
| 304 base::ObserverList<PageLoadMetricsObserver, true> observers_; | |
| 305 | 311 |
| 306 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserver); | 312 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserver); |
| 307 }; | 313 }; |
| 308 | 314 |
| 309 } // namespace page_load_metrics | 315 } // namespace page_load_metrics |
| 310 | 316 |
| 311 #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_O
BSERVER_H_ | 317 #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_O
BSERVER_H_ |
| OLD | NEW |