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

Side by Side Diff: chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc

Issue 2699933003: Generalize abort tracking to page end state tracking (Closed)
Patch Set: fix comment Created 3 years, 10 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 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 #include "chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_ observer.h" 5 #include "chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_ observer.h"
6 #include <string> 6 #include <string>
7 7
8 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" 10 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
11 #include "chrome/common/page_load_metrics/page_load_timing.h" 11 #include "chrome/common/page_load_metrics/page_load_timing.h"
12 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 12 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
13 13
14 using page_load_metrics::UserAbortType; 14 using page_load_metrics::PageAbortReason;
15 15
16 namespace internal { 16 namespace internal {
17 17
18 const char kHistogramFromGWSDomContentLoaded[] = 18 const char kHistogramFromGWSDomContentLoaded[] =
19 "PageLoad.Clients.FromGoogleSearch.DocumentTiming." 19 "PageLoad.Clients.FromGoogleSearch.DocumentTiming."
20 "NavigationToDOMContentLoadedEventFired"; 20 "NavigationToDOMContentLoadedEventFired";
21 const char kHistogramFromGWSLoad[] = 21 const char kHistogramFromGWSLoad[] =
22 "PageLoad.Clients.FromGoogleSearch.DocumentTiming." 22 "PageLoad.Clients.FromGoogleSearch.DocumentTiming."
23 "NavigationToLoadEventFired"; 23 "NavigationToLoadEventFired";
24 const char kHistogramFromGWSFirstPaint[] = 24 const char kHistogramFromGWSFirstPaint[] =
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 "PageLoad.Clients.FromGoogleSearch.Experimental.AbortTiming.Background." 93 "PageLoad.Clients.FromGoogleSearch.Experimental.AbortTiming.Background."
94 "AfterCommit.BeforePaint"; 94 "AfterCommit.BeforePaint";
95 const char kHistogramFromGWSAbortBackgroundBeforeInteraction[] = 95 const char kHistogramFromGWSAbortBackgroundBeforeInteraction[] =
96 "PageLoad.Clients.FromGoogleSearch.Experimental.AbortTiming.Background." 96 "PageLoad.Clients.FromGoogleSearch.Experimental.AbortTiming.Background."
97 "AfterPaint.BeforeInteraction"; 97 "AfterPaint.BeforeInteraction";
98 98
99 } // namespace internal 99 } // namespace internal
100 100
101 namespace { 101 namespace {
102 102
103 void LogCommittedAbortsBeforePaint(UserAbortType abort_type, 103 void LogCommittedAbortsBeforePaint(PageAbortReason abort_reason,
104 base::TimeDelta time_to_abort) { 104 base::TimeDelta page_end_time) {
105 switch (abort_type) { 105 switch (abort_reason) {
106 case UserAbortType::ABORT_STOP: 106 case PageAbortReason::ABORT_STOP:
107 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforePaint, 107 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforePaint,
108 time_to_abort); 108 page_end_time);
109 break; 109 break;
110 case UserAbortType::ABORT_CLOSE: 110 case PageAbortReason::ABORT_CLOSE:
111 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortCloseBeforePaint, 111 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortCloseBeforePaint,
112 time_to_abort); 112 page_end_time);
113 break; 113 break;
114 case UserAbortType::ABORT_NEW_NAVIGATION: 114 case PageAbortReason::ABORT_NEW_NAVIGATION:
115 PAGE_LOAD_HISTOGRAM( 115 PAGE_LOAD_HISTOGRAM(
116 internal::kHistogramFromGWSAbortNewNavigationBeforePaint, 116 internal::kHistogramFromGWSAbortNewNavigationBeforePaint,
117 time_to_abort); 117 page_end_time);
118 break; 118 break;
119 case UserAbortType::ABORT_RELOAD: 119 case PageAbortReason::ABORT_RELOAD:
120 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortReloadBeforePaint, 120 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortReloadBeforePaint,
121 time_to_abort); 121 page_end_time);
122 break; 122 break;
123 case UserAbortType::ABORT_FORWARD_BACK: 123 case PageAbortReason::ABORT_FORWARD_BACK:
124 PAGE_LOAD_HISTOGRAM( 124 PAGE_LOAD_HISTOGRAM(
125 internal::kHistogramFromGWSAbortForwardBackBeforePaint, 125 internal::kHistogramFromGWSAbortForwardBackBeforePaint,
126 time_to_abort); 126 page_end_time);
127 break; 127 break;
128 case UserAbortType::ABORT_BACKGROUND: 128 case PageAbortReason::ABORT_BACKGROUND:
129 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortBackgroundBeforePaint, 129 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortBackgroundBeforePaint,
130 time_to_abort); 130 page_end_time);
131 break; 131 break;
132 default: 132 default:
133 // These should only be logged for provisional aborts. 133 // These should only be logged for provisional aborts.
134 DCHECK_NE(abort_type, UserAbortType::ABORT_OTHER); 134 DCHECK_NE(abort_reason, PageAbortReason::ABORT_OTHER);
135 break; 135 break;
136 } 136 }
137 } 137 }
138 138
139 void LogAbortsAfterPaintBeforeInteraction(UserAbortType abort_type, 139 void LogAbortsAfterPaintBeforeInteraction(
140 base::TimeDelta time_to_abort) { 140 const page_load_metrics::PageAbortInfo& abort_info) {
141 switch (abort_type) { 141 switch (abort_info.reason) {
142 case UserAbortType::ABORT_STOP: 142 case PageAbortReason::ABORT_STOP:
143 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforeInteraction, 143 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforeInteraction,
144 time_to_abort); 144 abort_info.time_to_abort);
145 break; 145 break;
146 case UserAbortType::ABORT_CLOSE: 146 case PageAbortReason::ABORT_CLOSE:
147 PAGE_LOAD_HISTOGRAM( 147 PAGE_LOAD_HISTOGRAM(
148 internal::kHistogramFromGWSAbortCloseBeforeInteraction, 148 internal::kHistogramFromGWSAbortCloseBeforeInteraction,
149 time_to_abort); 149 abort_info.time_to_abort);
150 break; 150 break;
151 case UserAbortType::ABORT_NEW_NAVIGATION: 151 case PageAbortReason::ABORT_NEW_NAVIGATION:
152 PAGE_LOAD_HISTOGRAM( 152 PAGE_LOAD_HISTOGRAM(
153 internal::kHistogramFromGWSAbortNewNavigationBeforeInteraction, 153 internal::kHistogramFromGWSAbortNewNavigationBeforeInteraction,
154 time_to_abort); 154 abort_info.time_to_abort);
155 break; 155 break;
156 case UserAbortType::ABORT_RELOAD: 156 case PageAbortReason::ABORT_RELOAD:
157 PAGE_LOAD_HISTOGRAM( 157 PAGE_LOAD_HISTOGRAM(
158 internal::kHistogramFromGWSAbortReloadBeforeInteraction, 158 internal::kHistogramFromGWSAbortReloadBeforeInteraction,
159 time_to_abort); 159 abort_info.time_to_abort);
160 break; 160 break;
161 case UserAbortType::ABORT_FORWARD_BACK: 161 case PageAbortReason::ABORT_FORWARD_BACK:
162 PAGE_LOAD_HISTOGRAM( 162 PAGE_LOAD_HISTOGRAM(
163 internal::kHistogramFromGWSAbortForwardBackBeforeInteraction, 163 internal::kHistogramFromGWSAbortForwardBackBeforeInteraction,
164 time_to_abort); 164 abort_info.time_to_abort);
165 break; 165 break;
166 case UserAbortType::ABORT_BACKGROUND: 166 case PageAbortReason::ABORT_BACKGROUND:
167 PAGE_LOAD_HISTOGRAM( 167 PAGE_LOAD_HISTOGRAM(
168 internal::kHistogramFromGWSAbortBackgroundBeforeInteraction, 168 internal::kHistogramFromGWSAbortBackgroundBeforeInteraction,
169 time_to_abort); 169 abort_info.time_to_abort);
170 break; 170 break;
171 default: 171 default:
172 // These should only be logged for provisional aborts. 172 // These should only be logged for provisional aborts.
173 DCHECK_NE(abort_type, UserAbortType::ABORT_OTHER); 173 DCHECK_NE(abort_info.reason, PageAbortReason::ABORT_OTHER);
174 break; 174 break;
175 } 175 }
176 } 176 }
177 177
178 void LogProvisionalAborts(UserAbortType abort_type, 178 void LogProvisionalAborts(const page_load_metrics::PageAbortInfo& abort_info) {
179 base::TimeDelta time_to_abort) { 179 switch (abort_info.reason) {
180 switch (abort_type) { 180 case PageAbortReason::ABORT_STOP:
181 case UserAbortType::ABORT_STOP:
182 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforeCommit, 181 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortStopBeforeCommit,
183 time_to_abort); 182 abort_info.time_to_abort);
184 break; 183 break;
185 case UserAbortType::ABORT_CLOSE: 184 case PageAbortReason::ABORT_CLOSE:
186 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortCloseBeforeCommit, 185 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortCloseBeforeCommit,
187 time_to_abort); 186 abort_info.time_to_abort);
188 break; 187 break;
189 case UserAbortType::ABORT_OTHER: 188 case PageAbortReason::ABORT_OTHER:
190 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortOtherBeforeCommit, 189 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortOtherBeforeCommit,
191 time_to_abort); 190 abort_info.time_to_abort);
192 break; 191 break;
193 case UserAbortType::ABORT_NEW_NAVIGATION: 192 case PageAbortReason::ABORT_NEW_NAVIGATION:
194 PAGE_LOAD_HISTOGRAM( 193 PAGE_LOAD_HISTOGRAM(
195 internal::kHistogramFromGWSAbortNewNavigationBeforeCommit, 194 internal::kHistogramFromGWSAbortNewNavigationBeforeCommit,
196 time_to_abort); 195 abort_info.time_to_abort);
197 break; 196 break;
198 case UserAbortType::ABORT_RELOAD: 197 case PageAbortReason::ABORT_RELOAD:
199 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortReloadBeforeCommit, 198 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSAbortReloadBeforeCommit,
200 time_to_abort); 199 abort_info.time_to_abort);
201 break; 200 break;
202 case UserAbortType::ABORT_FORWARD_BACK: 201 case PageAbortReason::ABORT_FORWARD_BACK:
203 PAGE_LOAD_HISTOGRAM( 202 PAGE_LOAD_HISTOGRAM(
204 internal::kHistogramFromGWSAbortForwardBackBeforeCommit, 203 internal::kHistogramFromGWSAbortForwardBackBeforeCommit,
205 time_to_abort); 204 abort_info.time_to_abort);
206 break; 205 break;
207 case UserAbortType::ABORT_BACKGROUND: 206 case PageAbortReason::ABORT_BACKGROUND:
208 PAGE_LOAD_HISTOGRAM( 207 PAGE_LOAD_HISTOGRAM(
209 internal::kHistogramFromGWSAbortBackgroundBeforeCommit, 208 internal::kHistogramFromGWSAbortBackgroundBeforeCommit,
210 time_to_abort); 209 abort_info.time_to_abort);
211 break; 210 break;
212 default: 211 default:
213 NOTREACHED(); 212 NOTREACHED();
214 break; 213 break;
215 } 214 }
216 } 215 }
217 216
218 bool WasAbortedInForeground( 217 bool WasAbortedInForeground(
219 UserAbortType abort_type, 218 const page_load_metrics::PageLoadExtraInfo& info,
220 const base::Optional<base::TimeDelta>& time_to_abort, 219 const page_load_metrics::PageAbortInfo& abort_info) {
221 const page_load_metrics::PageLoadExtraInfo& info) { 220 if (!info.started_in_foreground ||
222 if (!time_to_abort) 221 abort_info.reason == PageAbortReason::ABORT_NONE)
223 return false; 222 return false;
224 if (abort_type == UserAbortType::ABORT_NONE) 223
225 return false; 224 base::Optional<base::TimeDelta> time_to_abort(abort_info.time_to_abort);
226 if (WasStartedInForegroundOptionalEventInForeground(time_to_abort, info)) 225 if (WasStartedInForegroundOptionalEventInForeground(time_to_abort, info))
227 return true; 226 return true;
228 if (!info.started_in_foreground)
229 return false;
230 227
231 const base::TimeDelta time_to_abort_val = time_to_abort.value();
232 const base::TimeDelta time_to_first_background = 228 const base::TimeDelta time_to_first_background =
233 info.first_background_time.value(); 229 info.first_background_time.value();
234 DCHECK_GT(time_to_abort_val, time_to_first_background); 230 DCHECK_GT(abort_info.time_to_abort, time_to_first_background);
235 base::TimeDelta background_abort_delta = 231 base::TimeDelta background_abort_delta =
236 time_to_abort_val - time_to_first_background; 232 abort_info.time_to_abort - time_to_first_background;
237 // Consider this a foregrounded abort if it occurred within 100ms of a 233 // Consider this a foregrounded abort if it occurred within 100ms of a
238 // background. This is needed for closing some tabs, where the signal for 234 // background. This is needed for closing some tabs, where the signal for
239 // background is often slightly ahead of the signal for close. 235 // background is often slightly ahead of the signal for close.
240 if (background_abort_delta.InMilliseconds() < 100) 236 if (background_abort_delta.InMilliseconds() < 100)
241 return true; 237 return true;
242 return false; 238 return false;
243 } 239 }
244 240
245 bool WasAbortedBeforeInteraction( 241 bool WasAbortedBeforeInteraction(
246 UserAbortType abort_type, 242 const page_load_metrics::PageAbortInfo& abort_info,
247 const base::Optional<base::TimeDelta>& time_to_interaction, 243 const base::Optional<base::TimeDelta>& time_to_interaction) {
248 const base::Optional<base::TimeDelta>& time_to_abort) {
249 // These conditions should be guaranteed by the call to 244 // These conditions should be guaranteed by the call to
250 // WasAbortedInForeground, which is called before WasAbortedBeforeInteraction 245 // WasAbortedInForeground, which is called before WasAbortedBeforeInteraction
251 // gets invoked. 246 // gets invoked.
252 DCHECK(time_to_abort); 247 DCHECK(abort_info.reason != PageAbortReason::ABORT_NONE);
253 DCHECK(abort_type != UserAbortType::ABORT_NONE);
254 248
255 if (!time_to_interaction) 249 if (!time_to_interaction)
256 return true; 250 return true;
257 // For the case the abort is a reload or forward_back. Since pull to 251 // For the case the abort is a reload or forward_back. Since pull to
258 // reload / forward_back is the most common user case such aborts being 252 // reload / forward_back is the most common user case such aborts being
259 // triggered, add a sanitization threshold here: if the first user 253 // triggered, add a sanitization threshold here: if the first user
260 // interaction are received before a reload / forward_back in a very 254 // interaction are received before a reload / forward_back in a very
261 // short time, treat the interaction as a gesture to perform the abort. 255 // short time, treat the interaction as a gesture to perform the abort.
262 256
263 // Why 1000ms? 257 // Why 1000ms?
264 // 1000ms is enough to perform a pull to reload / forward_back gesture. 258 // 1000ms is enough to perform a pull to reload / forward_back gesture.
265 // It's also too short a time for a user to consume any content 259 // It's also too short a time for a user to consume any content
266 // revealed by the interaction. 260 // revealed by the interaction.
267 if (abort_type == UserAbortType::ABORT_RELOAD || 261 if (abort_info.reason == PageAbortReason::ABORT_RELOAD ||
268 abort_type == UserAbortType::ABORT_FORWARD_BACK) { 262 abort_info.reason == PageAbortReason::ABORT_FORWARD_BACK) {
269 return time_to_interaction.value() + 263 return time_to_interaction.value() +
270 base::TimeDelta::FromMilliseconds(1000) > 264 base::TimeDelta::FromMilliseconds(1000) >
271 time_to_abort; 265 abort_info.time_to_abort;
272 } else { 266 } else {
273 return time_to_interaction > time_to_abort; 267 return time_to_interaction > abort_info.time_to_abort;
274 } 268 }
275 } 269 }
276 270
277 } // namespace 271 } // namespace
278 272
279 // See 273 // See
280 // https://docs.google.com/document/d/1jNPZ6Aeh0KV6umw1yZrrkfXRfxWNruwu7FELLx_cp Og/edit 274 // https://docs.google.com/document/d/1jNPZ6Aeh0KV6umw1yZrrkfXRfxWNruwu7FELLx_cp Og/edit
281 // for additional details. 275 // for additional details.
282 276
283 // static 277 // static
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 const blink::WebInputEvent& event) { 519 const blink::WebInputEvent& event) {
526 logger_.OnUserInput(event); 520 logger_.OnUserInput(event);
527 } 521 }
528 522
529 void FromGWSPageLoadMetricsLogger::OnComplete( 523 void FromGWSPageLoadMetricsLogger::OnComplete(
530 const page_load_metrics::PageLoadTiming& timing, 524 const page_load_metrics::PageLoadTiming& timing,
531 const page_load_metrics::PageLoadExtraInfo& extra_info) { 525 const page_load_metrics::PageLoadExtraInfo& extra_info) {
532 if (!ShouldLogPostCommitMetrics(extra_info.url)) 526 if (!ShouldLogPostCommitMetrics(extra_info.url))
533 return; 527 return;
534 528
535 UserAbortType abort_type = extra_info.abort_type; 529 page_load_metrics::PageAbortInfo abort_info = GetPageAbortInfo(extra_info);
536 if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info)) 530 if (!WasAbortedInForeground(extra_info, abort_info))
537 return; 531 return;
538 532
539 // If we did not receive any timing IPCs from the render process, we can't 533 // If we did not receive any timing IPCs from the render process, we can't
540 // know for certain if the page was truly aborted before paint, or if the 534 // know for certain if the page was truly aborted before paint, or if the
541 // abort happened before we received the IPC from the render process. Thus, we 535 // abort happened before we received the IPC from the render process. Thus, we
542 // do not log aborts for these page loads. Tracked page loads that receive no 536 // do not log aborts for these page loads. Tracked page loads that receive no
543 // timing IPCs are tracked via the ERR_NO_IPCS_RECEIVED error code in the 537 // timing IPCs are tracked via the ERR_NO_IPCS_RECEIVED error code in the
544 // PageLoad.Events.InternalError histogram, so we can keep track of how often 538 // PageLoad.Events.InternalError histogram, so we can keep track of how often
545 // this happens. 539 // this happens.
546 if (timing.IsEmpty()) 540 if (timing.IsEmpty())
547 return; 541 return;
548 542
549 base::TimeDelta time_to_abort = extra_info.time_to_abort.value(); 543 if (!timing.first_paint || timing.first_paint >= abort_info.time_to_abort) {
550 if (!timing.first_paint || timing.first_paint >= time_to_abort) { 544 LogCommittedAbortsBeforePaint(abort_info.reason, abort_info.time_to_abort);
551 LogCommittedAbortsBeforePaint(abort_type, time_to_abort); 545 } else if (WasAbortedBeforeInteraction(abort_info,
552 } else if (WasAbortedBeforeInteraction(abort_type, 546 first_user_interaction_after_paint_)) {
553 first_user_interaction_after_paint_, 547 LogAbortsAfterPaintBeforeInteraction(abort_info);
554 extra_info.time_to_abort)) {
555 LogAbortsAfterPaintBeforeInteraction(abort_type, time_to_abort);
556 } 548 }
557 } 549 }
558 550
559 void FromGWSPageLoadMetricsLogger::OnFailedProvisionalLoad( 551 void FromGWSPageLoadMetricsLogger::OnFailedProvisionalLoad(
560 const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info, 552 const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info,
561 const page_load_metrics::PageLoadExtraInfo& extra_info) { 553 const page_load_metrics::PageLoadExtraInfo& extra_info) {
562 if (!ShouldLogFailedProvisionalLoadMetrics()) 554 if (!ShouldLogFailedProvisionalLoadMetrics())
563 return; 555 return;
564 556
565 UserAbortType abort_type = extra_info.abort_type; 557 page_load_metrics::PageAbortInfo abort_info = GetPageAbortInfo(extra_info);
566 if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info)) 558 if (!WasAbortedInForeground(extra_info, abort_info))
567 return; 559 return;
568 560
569 LogProvisionalAborts(abort_type, extra_info.time_to_abort.value()); 561 LogProvisionalAborts(abort_info);
570 } 562 }
571 563
572 bool FromGWSPageLoadMetricsLogger::ShouldLogFailedProvisionalLoadMetrics() { 564 bool FromGWSPageLoadMetricsLogger::ShouldLogFailedProvisionalLoadMetrics() {
573 // See comment in ShouldLogPostCommitMetrics above the call to 565 // See comment in ShouldLogPostCommitMetrics above the call to
574 // IsGoogleSearchHostname for more info on this if test. 566 // IsGoogleSearchHostname for more info on this if test.
575 if (provisional_url_has_search_hostname_) 567 if (provisional_url_has_search_hostname_)
576 return false; 568 return false;
577 569
578 return previously_committed_url_is_search_results_ || 570 return previously_committed_url_is_search_results_ ||
579 previously_committed_url_is_search_redirector_; 571 previously_committed_url_is_search_redirector_;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 698 }
707 699
708 void FromGWSPageLoadMetricsLogger::OnUserInput( 700 void FromGWSPageLoadMetricsLogger::OnUserInput(
709 const blink::WebInputEvent& event) { 701 const blink::WebInputEvent& event) {
710 if (first_paint_triggered_ && !first_user_interaction_after_paint_) { 702 if (first_paint_triggered_ && !first_user_interaction_after_paint_) {
711 DCHECK(!navigation_start_.is_null()); 703 DCHECK(!navigation_start_.is_null());
712 first_user_interaction_after_paint_ = 704 first_user_interaction_after_paint_ =
713 base::TimeTicks::Now() - navigation_start_; 705 base::TimeTicks::Now() - navigation_start_;
714 } 706 }
715 } 707 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698