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

Side by Side Diff: chrome/browser/page_load_metrics/page_load_tracker.cc

Issue 2874663005: [Page Load Metrics] Add mojom file to page load metrics. (Closed)
Patch Set: rebase Created 3 years, 7 months 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 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 #include "chrome/browser/page_load_metrics/page_load_tracker.h" 5 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // second. 121 // second.
122 bool EventsInOrder(const base::Optional<base::TimeDelta>& first, 122 bool EventsInOrder(const base::Optional<base::TimeDelta>& first,
123 const base::Optional<base::TimeDelta>& second) { 123 const base::Optional<base::TimeDelta>& second) {
124 if (!second) { 124 if (!second) {
125 return true; 125 return true;
126 } 126 }
127 return first && first <= second; 127 return first && first <= second;
128 } 128 }
129 129
130 internal::PageLoadTimingStatus IsValidPageLoadTiming( 130 internal::PageLoadTimingStatus IsValidPageLoadTiming(
131 const PageLoadTiming& timing) { 131 const mojom::PageLoadTiming& timing) {
132 if (timing.IsEmpty()) 132 if (page_load_metrics::IsEmpty(timing))
133 return internal::INVALID_EMPTY_TIMING; 133 return internal::INVALID_EMPTY_TIMING;
134 134
135 // If we have a non-empty timing, it should always have a navigation start. 135 // If we have a non-empty timing, it should always have a navigation start.
136 if (timing.navigation_start.is_null()) { 136 if (timing.navigation_start.is_null()) {
137 LOG(ERROR) << "Received null navigation_start."; 137 LOG(ERROR) << "Received null navigation_start.";
138 return internal::INVALID_NULL_NAVIGATION_START; 138 return internal::INVALID_NULL_NAVIGATION_START;
139 } 139 }
140 140
141 // Verify proper ordering between the various timings. 141 // Verify proper ordering between the various timings.
142 142
143 if (!EventsInOrder(timing.response_start, timing.parse_timing.parse_start)) { 143 if (!EventsInOrder(timing.response_start, timing.parse_timing->parse_start)) {
144 // We sometimes get a zero response_start with a non-zero parse start. See 144 // We sometimes get a zero response_start with a non-zero parse start. See
145 // crbug.com/590212. 145 // crbug.com/590212.
146 LOG(ERROR) << "Invalid response_start " << timing.response_start 146 LOG(ERROR) << "Invalid response_start " << timing.response_start
147 << " for parse_start " << timing.parse_timing.parse_start; 147 << " for parse_start " << timing.parse_timing->parse_start;
148 // When browser-side navigation is enabled, we sometimes encounter this 148 // When browser-side navigation is enabled, we sometimes encounter this
149 // error case. For now, we disable reporting of this error, since most 149 // error case. For now, we disable reporting of this error, since most
150 // PageLoadMetricsObservers don't care about response_start and we want to 150 // PageLoadMetricsObservers don't care about response_start and we want to
151 // see how much closer fixing this error will get us to page load metrics 151 // see how much closer fixing this error will get us to page load metrics
152 // being consistent with and without browser side navigation enabled. See 152 // being consistent with and without browser side navigation enabled. See
153 // crbug.com/716587 for more details. 153 // crbug.com/716587 for more details.
154 // 154 //
155 // return internal::INVALID_ORDER_RESPONSE_START_PARSE_START; 155 // return internal::INVALID_ORDER_RESPONSE_START_PARSE_START;
156 } 156 }
157 157
158 if (!EventsInOrder(timing.parse_timing.parse_start, 158 if (!EventsInOrder(timing.parse_timing->parse_start,
159 timing.parse_timing.parse_stop)) { 159 timing.parse_timing->parse_stop)) {
160 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing.parse_start 160 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing->parse_start
161 << " for parse_stop " << timing.parse_timing.parse_stop; 161 << " for parse_stop " << timing.parse_timing->parse_stop;
162 return internal::INVALID_ORDER_PARSE_START_PARSE_STOP; 162 return internal::INVALID_ORDER_PARSE_START_PARSE_STOP;
163 } 163 }
164 164
165 if (timing.parse_timing.parse_stop) { 165 if (timing.parse_timing->parse_stop) {
166 const base::TimeDelta parse_duration = 166 const base::TimeDelta parse_duration =
167 timing.parse_timing.parse_stop.value() - 167 timing.parse_timing->parse_stop.value() -
168 timing.parse_timing.parse_start.value(); 168 timing.parse_timing->parse_start.value();
169 if (timing.parse_timing.parse_blocked_on_script_load_duration > 169 if (timing.parse_timing->parse_blocked_on_script_load_duration >
170 parse_duration) { 170 parse_duration) {
171 LOG(ERROR) << "Invalid parse_blocked_on_script_load_duration " 171 LOG(ERROR) << "Invalid parse_blocked_on_script_load_duration "
172 << timing.parse_timing.parse_blocked_on_script_load_duration 172 << timing.parse_timing->parse_blocked_on_script_load_duration
173 << " for parse duration " << parse_duration; 173 << " for parse duration " << parse_duration;
174 return internal::INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE; 174 return internal::INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE;
175 } 175 }
176 if (timing.parse_timing.parse_blocked_on_script_execution_duration > 176 if (timing.parse_timing->parse_blocked_on_script_execution_duration >
177 parse_duration) { 177 parse_duration) {
178 LOG(ERROR) 178 LOG(ERROR)
179 << "Invalid parse_blocked_on_script_execution_duration " 179 << "Invalid parse_blocked_on_script_execution_duration "
180 << timing.parse_timing.parse_blocked_on_script_execution_duration 180 << timing.parse_timing->parse_blocked_on_script_execution_duration
181 << " for parse duration " << parse_duration; 181 << " for parse duration " << parse_duration;
182 return internal::INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE; 182 return internal::INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE;
183 } 183 }
184 } 184 }
185 185
186 if (timing.parse_timing 186 if (timing.parse_timing
187 .parse_blocked_on_script_load_from_document_write_duration > 187 ->parse_blocked_on_script_load_from_document_write_duration >
188 timing.parse_timing.parse_blocked_on_script_load_duration) { 188 timing.parse_timing->parse_blocked_on_script_load_duration) {
189 LOG(ERROR) 189 LOG(ERROR)
190 << "Invalid parse_blocked_on_script_load_from_document_write_duration " 190 << "Invalid parse_blocked_on_script_load_from_document_write_duration "
191 << timing.parse_timing 191 << timing.parse_timing
192 .parse_blocked_on_script_load_from_document_write_duration 192 ->parse_blocked_on_script_load_from_document_write_duration
193 << " for parse_blocked_on_script_load_duration " 193 << " for parse_blocked_on_script_load_duration "
194 << timing.parse_timing.parse_blocked_on_script_load_duration; 194 << timing.parse_timing->parse_blocked_on_script_load_duration;
195 return internal::INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD; 195 return internal::INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD;
196 } 196 }
197 197
198 if (timing.parse_timing 198 if (timing.parse_timing
199 .parse_blocked_on_script_execution_from_document_write_duration > 199 ->parse_blocked_on_script_execution_from_document_write_duration >
200 timing.parse_timing.parse_blocked_on_script_execution_duration) { 200 timing.parse_timing->parse_blocked_on_script_execution_duration) {
201 LOG(ERROR) 201 LOG(ERROR)
202 << "Invalid " 202 << "Invalid "
203 "parse_blocked_on_script_execution_from_document_write_duration " 203 "parse_blocked_on_script_execution_from_document_write_duration "
204 << timing.parse_timing 204 << timing.parse_timing
205 .parse_blocked_on_script_execution_from_document_write_duration 205 ->parse_blocked_on_script_execution_from_document_write_duration
206 << " for parse_blocked_on_script_execution_duration " 206 << " for parse_blocked_on_script_execution_duration "
207 << timing.parse_timing.parse_blocked_on_script_execution_duration; 207 << timing.parse_timing->parse_blocked_on_script_execution_duration;
208 return internal::INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC; 208 return internal::INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC;
209 } 209 }
210 210
211 if (!EventsInOrder(timing.parse_timing.parse_stop, 211 if (!EventsInOrder(timing.parse_timing->parse_stop,
212 timing.document_timing.dom_content_loaded_event_start)) { 212 timing.document_timing->dom_content_loaded_event_start)) {
213 LOG(ERROR) << "Invalid parse_stop " << timing.parse_timing.parse_stop 213 LOG(ERROR) << "Invalid parse_stop " << timing.parse_timing->parse_stop
214 << " for dom_content_loaded_event_start " 214 << " for dom_content_loaded_event_start "
215 << timing.document_timing.dom_content_loaded_event_start; 215 << timing.document_timing->dom_content_loaded_event_start;
216 return internal::INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED; 216 return internal::INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED;
217 } 217 }
218 218
219 if (!EventsInOrder(timing.document_timing.dom_content_loaded_event_start, 219 if (!EventsInOrder(timing.document_timing->dom_content_loaded_event_start,
220 timing.document_timing.load_event_start)) { 220 timing.document_timing->load_event_start)) {
221 LOG(ERROR) << "Invalid dom_content_loaded_event_start " 221 LOG(ERROR) << "Invalid dom_content_loaded_event_start "
222 << timing.document_timing.dom_content_loaded_event_start 222 << timing.document_timing->dom_content_loaded_event_start
223 << " for load_event_start " 223 << " for load_event_start "
224 << timing.document_timing.load_event_start; 224 << timing.document_timing->load_event_start;
225 return internal::INVALID_ORDER_DOM_CONTENT_LOADED_LOAD; 225 return internal::INVALID_ORDER_DOM_CONTENT_LOADED_LOAD;
226 } 226 }
227 227
228 if (!EventsInOrder(timing.parse_timing.parse_start, 228 if (!EventsInOrder(timing.parse_timing->parse_start,
229 timing.document_timing.first_layout)) { 229 timing.document_timing->first_layout)) {
230 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing.parse_start 230 LOG(ERROR) << "Invalid parse_start " << timing.parse_timing->parse_start
231 << " for first_layout " << timing.document_timing.first_layout; 231 << " for first_layout " << timing.document_timing->first_layout;
232 return internal::INVALID_ORDER_PARSE_START_FIRST_LAYOUT; 232 return internal::INVALID_ORDER_PARSE_START_FIRST_LAYOUT;
233 } 233 }
234 234
235 if (!EventsInOrder(timing.document_timing.first_layout, 235 if (!EventsInOrder(timing.document_timing->first_layout,
236 timing.paint_timing.first_paint)) { 236 timing.paint_timing->first_paint)) {
237 // This can happen when we process an XHTML document that doesn't contain 237 // This can happen when we process an XHTML document that doesn't contain
238 // well formed XML. See crbug.com/627607. 238 // well formed XML. See crbug.com/627607.
239 DLOG(ERROR) << "Invalid first_layout " 239 DLOG(ERROR) << "Invalid first_layout "
240 << timing.document_timing.first_layout << " for first_paint " 240 << timing.document_timing->first_layout << " for first_paint "
241 << timing.paint_timing.first_paint; 241 << timing.paint_timing->first_paint;
242 return internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT; 242 return internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT;
243 } 243 }
244 244
245 if (!EventsInOrder(timing.paint_timing.first_paint, 245 if (!EventsInOrder(timing.paint_timing->first_paint,
246 timing.paint_timing.first_text_paint)) { 246 timing.paint_timing->first_text_paint)) {
247 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 247 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
248 << " for first_text_paint " 248 << " for first_text_paint "
249 << timing.paint_timing.first_text_paint; 249 << timing.paint_timing->first_text_paint;
250 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT; 250 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT;
251 } 251 }
252 252
253 if (!EventsInOrder(timing.paint_timing.first_paint, 253 if (!EventsInOrder(timing.paint_timing->first_paint,
254 timing.paint_timing.first_image_paint)) { 254 timing.paint_timing->first_image_paint)) {
255 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 255 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
256 << " for first_image_paint " 256 << " for first_image_paint "
257 << timing.paint_timing.first_image_paint; 257 << timing.paint_timing->first_image_paint;
258 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT; 258 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT;
259 } 259 }
260 260
261 if (!EventsInOrder(timing.paint_timing.first_paint, 261 if (!EventsInOrder(timing.paint_timing->first_paint,
262 timing.paint_timing.first_contentful_paint)) { 262 timing.paint_timing->first_contentful_paint)) {
263 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 263 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
264 << " for first_contentful_paint " 264 << " for first_contentful_paint "
265 << timing.paint_timing.first_contentful_paint; 265 << timing.paint_timing->first_contentful_paint;
266 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT; 266 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT;
267 } 267 }
268 268
269 if (!EventsInOrder(timing.paint_timing.first_paint, 269 if (!EventsInOrder(timing.paint_timing->first_paint,
270 timing.paint_timing.first_meaningful_paint)) { 270 timing.paint_timing->first_meaningful_paint)) {
271 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing.first_paint 271 LOG(ERROR) << "Invalid first_paint " << timing.paint_timing->first_paint
272 << " for first_meaningful_paint " 272 << " for first_meaningful_paint "
273 << timing.paint_timing.first_meaningful_paint; 273 << timing.paint_timing->first_meaningful_paint;
274 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT; 274 return internal::INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT;
275 } 275 }
276 276
277 return internal::VALID; 277 return internal::VALID;
278 } 278 }
279 279
280 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) { 280 void RecordAppBackgroundPageLoadCompleted(bool completed_after_background) {
281 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground, 281 UMA_HISTOGRAM_BOOLEAN(internal::kPageLoadCompletedAfterAppBackground,
282 completed_after_background); 282 completed_after_background);
283 } 283 }
284 284
285 void DispatchObserverTimingCallbacks(PageLoadMetricsObserver* observer, 285 void DispatchObserverTimingCallbacks(
286 const PageLoadTiming& last_timing, 286 PageLoadMetricsObserver* observer,
287 const PageLoadTiming& new_timing, 287 const mojom::PageLoadTiming& last_timing,
288 const PageLoadMetadata& last_metadata, 288 const mojom::PageLoadTiming& new_timing,
289 const PageLoadExtraInfo& extra_info) { 289 const mojom::PageLoadMetadata& last_metadata,
290 const PageLoadExtraInfo& extra_info) {
290 if (extra_info.main_frame_metadata.behavior_flags != 291 if (extra_info.main_frame_metadata.behavior_flags !=
291 last_metadata.behavior_flags) 292 last_metadata.behavior_flags)
292 observer->OnLoadingBehaviorObserved(extra_info); 293 observer->OnLoadingBehaviorObserved(extra_info);
293 if (last_timing != new_timing) 294 if (!last_timing.Equals(new_timing))
294 observer->OnTimingUpdate(new_timing, extra_info); 295 observer->OnTimingUpdate(new_timing, extra_info);
295 if (new_timing.document_timing.dom_content_loaded_event_start && 296 if (new_timing.document_timing->dom_content_loaded_event_start &&
296 !last_timing.document_timing.dom_content_loaded_event_start) 297 !last_timing.document_timing->dom_content_loaded_event_start)
297 observer->OnDomContentLoadedEventStart(new_timing, extra_info); 298 observer->OnDomContentLoadedEventStart(new_timing, extra_info);
298 if (new_timing.document_timing.load_event_start && 299 if (new_timing.document_timing->load_event_start &&
299 !last_timing.document_timing.load_event_start) 300 !last_timing.document_timing->load_event_start)
300 observer->OnLoadEventStart(new_timing, extra_info); 301 observer->OnLoadEventStart(new_timing, extra_info);
301 if (new_timing.document_timing.first_layout && 302 if (new_timing.document_timing->first_layout &&
302 !last_timing.document_timing.first_layout) 303 !last_timing.document_timing->first_layout)
303 observer->OnFirstLayout(new_timing, extra_info); 304 observer->OnFirstLayout(new_timing, extra_info);
304 if (new_timing.paint_timing.first_paint && 305 if (new_timing.paint_timing->first_paint &&
305 !last_timing.paint_timing.first_paint) 306 !last_timing.paint_timing->first_paint)
306 observer->OnFirstPaint(new_timing, extra_info); 307 observer->OnFirstPaint(new_timing, extra_info);
307 if (new_timing.paint_timing.first_text_paint && 308 if (new_timing.paint_timing->first_text_paint &&
308 !last_timing.paint_timing.first_text_paint) 309 !last_timing.paint_timing->first_text_paint)
309 observer->OnFirstTextPaint(new_timing, extra_info); 310 observer->OnFirstTextPaint(new_timing, extra_info);
310 if (new_timing.paint_timing.first_image_paint && 311 if (new_timing.paint_timing->first_image_paint &&
311 !last_timing.paint_timing.first_image_paint) 312 !last_timing.paint_timing->first_image_paint)
312 observer->OnFirstImagePaint(new_timing, extra_info); 313 observer->OnFirstImagePaint(new_timing, extra_info);
313 if (new_timing.paint_timing.first_contentful_paint && 314 if (new_timing.paint_timing->first_contentful_paint &&
314 !last_timing.paint_timing.first_contentful_paint) 315 !last_timing.paint_timing->first_contentful_paint)
315 observer->OnFirstContentfulPaint(new_timing, extra_info); 316 observer->OnFirstContentfulPaint(new_timing, extra_info);
316 if (new_timing.paint_timing.first_meaningful_paint && 317 if (new_timing.paint_timing->first_meaningful_paint &&
317 !last_timing.paint_timing.first_meaningful_paint) 318 !last_timing.paint_timing->first_meaningful_paint)
318 observer->OnFirstMeaningfulPaint(new_timing, extra_info); 319 observer->OnFirstMeaningfulPaint(new_timing, extra_info);
319 if (new_timing.parse_timing.parse_start && 320 if (new_timing.parse_timing->parse_start &&
320 !last_timing.parse_timing.parse_start) 321 !last_timing.parse_timing->parse_start)
321 observer->OnParseStart(new_timing, extra_info); 322 observer->OnParseStart(new_timing, extra_info);
322 if (new_timing.parse_timing.parse_stop && 323 if (new_timing.parse_timing->parse_stop &&
323 !last_timing.parse_timing.parse_stop) 324 !last_timing.parse_timing->parse_stop)
324 observer->OnParseStop(new_timing, extra_info); 325 observer->OnParseStop(new_timing, extra_info);
325 } 326 }
326 327
327 } // namespace 328 } // namespace
328 329
329 PageLoadTracker::PageLoadTracker( 330 PageLoadTracker::PageLoadTracker(
330 bool in_foreground, 331 bool in_foreground,
331 PageLoadMetricsEmbedderInterface* embedder_interface, 332 PageLoadMetricsEmbedderInterface* embedder_interface,
332 const GURL& currently_committed_url, 333 const GURL& currently_committed_url,
333 content::NavigationHandle* navigation_handle, 334 content::NavigationHandle* navigation_handle,
334 UserInitiatedInfo user_initiated_info, 335 UserInitiatedInfo user_initiated_info,
335 int aborted_chain_size, 336 int aborted_chain_size,
336 int aborted_chain_size_same_url) 337 int aborted_chain_size_same_url)
337 : did_stop_tracking_(false), 338 : did_stop_tracking_(false),
338 app_entered_background_(false), 339 app_entered_background_(false),
339 navigation_start_(navigation_handle->NavigationStart()), 340 navigation_start_(navigation_handle->NavigationStart()),
340 url_(navigation_handle->GetURL()), 341 url_(navigation_handle->GetURL()),
341 start_url_(navigation_handle->GetURL()), 342 start_url_(navigation_handle->GetURL()),
342 did_commit_(false), 343 did_commit_(false),
343 page_end_reason_(END_NONE), 344 page_end_reason_(END_NONE),
344 page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()), 345 page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()),
345 started_in_foreground_(in_foreground), 346 started_in_foreground_(in_foreground),
347 timing_(CreatePageLoadTiming()),
346 page_transition_(navigation_handle->GetPageTransition()), 348 page_transition_(navigation_handle->GetPageTransition()),
347 user_initiated_info_(user_initiated_info), 349 user_initiated_info_(user_initiated_info),
348 aborted_chain_size_(aborted_chain_size), 350 aborted_chain_size_(aborted_chain_size),
349 aborted_chain_size_same_url_(aborted_chain_size_same_url), 351 aborted_chain_size_same_url_(aborted_chain_size_same_url),
350 embedder_interface_(embedder_interface) { 352 embedder_interface_(embedder_interface) {
351 DCHECK(!navigation_handle->HasCommitted()); 353 DCHECK(!navigation_handle->HasCommitted());
352 embedder_interface_->RegisterObservers(this); 354 embedder_interface_->RegisterObservers(this);
353 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnStart, navigation_handle, 355 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnStart, navigation_handle,
354 currently_committed_url, started_in_foreground_); 356 currently_committed_url, started_in_foreground_);
355 357
(...skipping 27 matching lines...) Expand all
383 if (!failed_provisional_load_info_) 385 if (!failed_provisional_load_info_)
384 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD); 386 RecordInternalError(ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD);
385 387
386 // Don't include any aborts that resulted in a new navigation, as the chain 388 // Don't include any aborts that resulted in a new navigation, as the chain
387 // length will be included in the aborter PageLoadTracker. 389 // length will be included in the aborter PageLoadTracker.
388 if (page_end_reason_ != END_RELOAD && 390 if (page_end_reason_ != END_RELOAD &&
389 page_end_reason_ != END_FORWARD_BACK && 391 page_end_reason_ != END_FORWARD_BACK &&
390 page_end_reason_ != END_NEW_NAVIGATION) { 392 page_end_reason_ != END_NEW_NAVIGATION) {
391 LogAbortChainHistograms(nullptr); 393 LogAbortChainHistograms(nullptr);
392 } 394 }
393 } else if (timing_.IsEmpty()) { 395 } else if (page_load_metrics::IsEmpty(*timing_)) {
394 RecordInternalError(ERR_NO_IPCS_RECEIVED); 396 RecordInternalError(ERR_NO_IPCS_RECEIVED);
395 } 397 }
396 398
397 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 399 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
398 for (const auto& observer : observers_) { 400 for (const auto& observer : observers_) {
399 if (failed_provisional_load_info_) { 401 if (failed_provisional_load_info_) {
400 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info); 402 observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info);
401 } else if (did_commit_) { 403 } else if (did_commit_) {
402 observer->OnComplete(timing_, info); 404 observer->OnComplete(*timing_, info);
403 } 405 }
404 } 406 }
405 } 407 }
406 408
407 void PageLoadTracker::LogAbortChainHistograms( 409 void PageLoadTracker::LogAbortChainHistograms(
408 content::NavigationHandle* final_navigation) { 410 content::NavigationHandle* final_navigation) {
409 if (aborted_chain_size_ == 0) 411 if (aborted_chain_size_ == 0)
410 return; 412 return;
411 // Note that this could be broken out by this navigation's abort type, if more 413 // Note that this could be broken out by this navigation's abort type, if more
412 // granularity is needed. Add one to the chain size to count the current 414 // granularity is needed. Add one to the chain size to count the current
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 // Only log the first time we background in a given page load. 461 // Only log the first time we background in a given page load.
460 if (background_time_.is_null()) { 462 if (background_time_.is_null()) {
461 // Make sure we either started in the foreground and haven't been 463 // Make sure we either started in the foreground and haven't been
462 // foregrounded yet, or started in the background and have already been 464 // foregrounded yet, or started in the background and have already been
463 // foregrounded. 465 // foregrounded.
464 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null()); 466 DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
465 background_time_ = base::TimeTicks::Now(); 467 background_time_ = base::TimeTicks::Now();
466 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_); 468 ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
467 } 469 }
468 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 470 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
469 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnHidden, timing_, info); 471 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnHidden, *timing_, info);
470 } 472 }
471 473
472 void PageLoadTracker::WebContentsShown() { 474 void PageLoadTracker::WebContentsShown() {
473 // Only log the first time we foreground in a given page load. 475 // Only log the first time we foreground in a given page load.
474 if (foreground_time_.is_null()) { 476 if (foreground_time_.is_null()) {
475 // Make sure we either started in the background and haven't been 477 // Make sure we either started in the background and haven't been
476 // backgrounded yet, or started in the foreground and have already been 478 // backgrounded yet, or started in the foreground and have already been
477 // backgrounded. 479 // backgrounded.
478 DCHECK_NE(started_in_foreground_, background_time_.is_null()); 480 DCHECK_NE(started_in_foreground_, background_time_.is_null());
479 foreground_time_ = base::TimeTicks::Now(); 481 foreground_time_ = base::TimeTicks::Now();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 544 }
543 545
544 void PageLoadTracker::FlushMetricsOnAppEnterBackground() { 546 void PageLoadTracker::FlushMetricsOnAppEnterBackground() {
545 if (!app_entered_background_) { 547 if (!app_entered_background_) {
546 RecordAppBackgroundPageLoadCompleted(false); 548 RecordAppBackgroundPageLoadCompleted(false);
547 app_entered_background_ = true; 549 app_entered_background_ = true;
548 } 550 }
549 551
550 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 552 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
551 INVOKE_AND_PRUNE_OBSERVERS(observers_, FlushMetricsOnAppEnterBackground, 553 INVOKE_AND_PRUNE_OBSERVERS(observers_, FlushMetricsOnAppEnterBackground,
552 timing_, info); 554 *timing_, info);
553 } 555 }
554 556
555 void PageLoadTracker::NotifyClientRedirectTo( 557 void PageLoadTracker::NotifyClientRedirectTo(
556 const PageLoadTracker& destination) { 558 const PageLoadTracker& destination) {
557 if (timing_.paint_timing.first_paint) { 559 if (timing_->paint_timing->first_paint) {
558 base::TimeTicks first_paint_time = 560 base::TimeTicks first_paint_time =
559 navigation_start() + timing_.paint_timing.first_paint.value(); 561 navigation_start() + timing_->paint_timing->first_paint.value();
560 base::TimeDelta first_paint_to_navigation; 562 base::TimeDelta first_paint_to_navigation;
561 if (destination.navigation_start() > first_paint_time) 563 if (destination.navigation_start() > first_paint_time)
562 first_paint_to_navigation = 564 first_paint_to_navigation =
563 destination.navigation_start() - first_paint_time; 565 destination.navigation_start() - first_paint_time;
564 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, 566 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation,
565 first_paint_to_navigation); 567 first_paint_to_navigation);
566 } else { 568 } else {
567 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); 569 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true);
568 } 570 }
569 } 571 }
570 572
571 void PageLoadTracker::UpdateChildFrameMetadata( 573 void PageLoadTracker::UpdateChildFrameMetadata(
572 const PageLoadMetadata& child_metadata) { 574 const mojom::PageLoadMetadata& child_metadata) {
573 // Merge the child loading behavior flags with any we've already observed, 575 // Merge the child loading behavior flags with any we've already observed,
574 // possibly from other child frames. 576 // possibly from other child frames.
575 const int last_child_loading_behavior_flags = 577 const int last_child_loading_behavior_flags =
576 child_frame_metadata_.behavior_flags; 578 child_frame_metadata_.behavior_flags;
577 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags; 579 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags;
578 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags) 580 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags)
579 return; 581 return;
580 582
581 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo()); 583 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo());
582 for (const auto& observer : observers_) { 584 for (const auto& observer : observers_) {
583 observer->OnLoadingBehaviorObserved(extra_info); 585 observer->OnLoadingBehaviorObserved(extra_info);
584 } 586 }
585 } 587 }
586 588
587 void PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, 589 void PageLoadTracker::UpdateTiming(
588 const PageLoadMetadata& new_metadata) { 590 const mojom::PageLoadTiming& new_timing,
591 const mojom::PageLoadMetadata& new_metadata) {
589 // Throw away IPCs that are not relevant to the current navigation. 592 // Throw away IPCs that are not relevant to the current navigation.
590 // Two timing structures cannot refer to the same navigation if they indicate 593 // Two timing structures cannot refer to the same navigation if they indicate
591 // that a navigation started at different times, so a new timing struct with a 594 // that a navigation started at different times, so a new timing struct with a
592 // different start time from an earlier struct is considered invalid. 595 // different start time from an earlier struct is considered invalid.
593 const bool valid_timing_descendent = 596 const bool valid_timing_descendent =
594 timing_.navigation_start.is_null() || 597 timing_->navigation_start.is_null() ||
595 timing_.navigation_start == new_timing.navigation_start; 598 timing_->navigation_start == new_timing.navigation_start;
596 if (!valid_timing_descendent) { 599 if (!valid_timing_descendent) {
597 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT); 600 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT);
598 return; 601 return;
599 } 602 }
600 603
601 // Ensure flags sent previously are still present in the new metadata fields. 604 // Ensure flags sent previously are still present in the new metadata fields.
602 const bool valid_behavior_descendent = 605 const bool valid_behavior_descendent =
603 (main_frame_metadata_.behavior_flags & new_metadata.behavior_flags) == 606 (main_frame_metadata_.behavior_flags & new_metadata.behavior_flags) ==
604 main_frame_metadata_.behavior_flags; 607 main_frame_metadata_.behavior_flags;
605 if (!valid_behavior_descendent) { 608 if (!valid_behavior_descendent) {
606 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT); 609 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT);
607 return; 610 return;
608 } 611 }
609 internal::PageLoadTimingStatus status = IsValidPageLoadTiming(new_timing); 612 internal::PageLoadTimingStatus status = IsValidPageLoadTiming(new_timing);
610 UMA_HISTOGRAM_ENUMERATION(internal::kPageLoadTimingStatus, status, 613 UMA_HISTOGRAM_ENUMERATION(internal::kPageLoadTimingStatus, status,
611 internal::LAST_PAGE_LOAD_TIMING_STATUS); 614 internal::LAST_PAGE_LOAD_TIMING_STATUS);
612 if (status != internal::VALID) { 615 if (status != internal::VALID) {
613 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING); 616 RecordInternalError(ERR_BAD_TIMING_IPC_INVALID_TIMING);
614 return; 617 return;
615 } 618 }
616 619
617 DCHECK(did_commit_); // OnCommit() must be called first. 620 DCHECK(did_commit_); // OnCommit() must be called first.
618 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo() 621 // There are some subtle ordering constraints here. GetPageLoadMetricsInfo()
619 // must be called before DispatchObserverTimingCallbacks, but its 622 // must be called before DispatchObserverTimingCallbacks, but its
620 // implementation depends on the state of main_frame_metadata_, so we need 623 // implementation depends on the state of main_frame_metadata_, so we need
621 // to update main_frame_metadata_ before calling GetPageLoadMetricsInfo. 624 // to update main_frame_metadata_ before calling GetPageLoadMetricsInfo.
622 // Thus, we make a copy of timing here, update timing_ and 625 // Thus, we make a copy of timing here, update timing_ and
623 // main_frame_metadata_, and then proceed to dispatch the observer timing 626 // main_frame_metadata_, and then proceed to dispatch the observer timing
624 // callbacks. 627 // callbacks.
625 const PageLoadTiming last_timing = timing_; 628 mojo::StructPtr<mojom::PageLoadTiming> last_timing = std::move(timing_);
626 timing_ = new_timing; 629 timing_ = new_timing.Clone();
627 630
628 const PageLoadMetadata last_metadata = main_frame_metadata_; 631 const mojom::PageLoadMetadata last_metadata = main_frame_metadata_;
629 main_frame_metadata_ = new_metadata; 632 main_frame_metadata_ = new_metadata;
630 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); 633 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
631 for (const auto& observer : observers_) { 634 for (const auto& observer : observers_) {
632 DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing, 635 DispatchObserverTimingCallbacks(observer.get(), *last_timing, new_timing,
633 last_metadata, info); 636 last_metadata, info);
634 } 637 }
635 } 638 }
636 639
637 void PageLoadTracker::OnStartedResource( 640 void PageLoadTracker::OnStartedResource(
638 const ExtraRequestStartInfo& extra_request_start_info) { 641 const ExtraRequestStartInfo& extra_request_start_info) {
639 for (const auto& observer : observers_) { 642 for (const auto& observer : observers_) {
640 observer->OnStartedResource(extra_request_start_info); 643 observer->OnStartedResource(extra_request_start_info);
641 } 644 }
642 } 645 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 observer->MediaStartedPlaying(video_type, is_in_main_frame); 822 observer->MediaStartedPlaying(video_type, is_in_main_frame);
820 } 823 }
821 824
822 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay, 825 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay,
823 base::TimeDelta actual_delay) { 826 base::TimeDelta actual_delay) {
824 for (const auto& observer : observers_) 827 for (const auto& observer : observers_)
825 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay); 828 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay);
826 } 829 }
827 830
828 } // namespace page_load_metrics 831 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698