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

Side by Side Diff: components/page_load_metrics/browser/metrics_web_contents_observer.h

Issue 1473153002: PageLoadMetricsObservers observe individual page loads (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase and update for s-w-r experiment Created 5 years 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 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
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
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 pointers outlives this
Randy Smith (Not in Mondays) 2015/12/03 01:20:42 nit: pointer (singular).
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698