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

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 7289020: Updating histograms to allow for experiments & log origin-based histograms. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/prerender/prerender_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/field_trial.h" 11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/favicon/favicon_tab_helper.h" 17 #include "chrome/browser/favicon/favicon_tab_helper.h"
18 #include "chrome/browser/prerender/prerender_contents.h" 18 #include "chrome/browser/prerender/prerender_contents.h"
19 #include "chrome/browser/prerender/prerender_final_status.h" 19 #include "chrome/browser/prerender/prerender_final_status.h"
20 #include "chrome/browser/prerender/prerender_history.h" 20 #include "chrome/browser/prerender/prerender_history.h"
21 #include "chrome/browser/prerender/prerender_observer.h" 21 #include "chrome/browser/prerender/prerender_observer.h"
22 #include "chrome/browser/prerender/prerender_tracker.h" 22 #include "chrome/browser/prerender/prerender_tracker.h"
23 #include "chrome/browser/prerender/prerender_util.h"
23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 25 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
25 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" 26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
26 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/render_messages.h" 28 #include "chrome/common/render_messages.h"
28 #include "content/browser/browser_thread.h" 29 #include "content/browser/browser_thread.h"
29 #include "content/browser/renderer_host/render_process_host.h" 30 #include "content/browser/renderer_host/render_process_host.h"
30 #include "content/browser/renderer_host/render_view_host.h" 31 #include "content/browser/renderer_host/render_view_host.h"
31 #include "content/browser/renderer_host/resource_dispatcher_host.h" 32 #include "content/browser/renderer_host/resource_dispatcher_host.h"
32 #include "content/browser/tab_contents/render_view_host_manager.h" 33 #include "content/browser/tab_contents/render_view_host_manager.h"
33 #include "content/browser/tab_contents/tab_contents.h" 34 #include "content/browser/tab_contents/tab_contents.h"
34 #include "content/browser/tab_contents/tab_contents_delegate.h" 35 #include "content/browser/tab_contents/tab_contents_delegate.h"
35 #include "content/common/notification_service.h" 36 #include "content/common/notification_service.h"
36 #include "googleurl/src/url_canon.h"
37 #include "googleurl/src/url_parse.h"
38 #include "googleurl/src/url_util.h"
39 37
40 namespace prerender { 38 namespace prerender {
41 39
42 namespace { 40 namespace {
43 41
44 // Time window for which we will record windowed PLT's from the last 42 // Time window for which we will record windowed PLT's from the last
45 // observed link rel=prefetch tag. 43 // observed link rel=prefetch tag.
46 const int kWindowDurationSeconds = 30; 44 const int kWindowDurationSeconds = 30;
47 45
48 // Time interval at which periodic cleanups are performed. 46 // Time interval at which periodic cleanups are performed.
(...skipping 12 matching lines...) Expand all
61 "OPTIONS", 59 "OPTIONS",
62 "POST", 60 "POST",
63 "TRACE", 61 "TRACE",
64 }; 62 };
65 63
66 // Length of prerender history, for display in chrome://net-internals 64 // Length of prerender history, for display in chrome://net-internals
67 const int kHistoryLength = 100; 65 const int kHistoryLength = 100;
68 66
69 } // namespace 67 } // namespace
70 68
69 // Helper macros for experiment-based and origin-based histogram reporting.
70 #define PREFIXED_HISTOGRAM(histogram) \
71 PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \
72 IsOriginExperimentWash(), histogram)
73
74 #define PREFIXED_HISTOGRAM_PRERENDER_MANAGER(pm, histogram) \
75 PREFIXED_HISTOGRAM_INTERNAL(pm->GetCurrentOrigin(), \
76 pm->GetCurrentExperimentId(), \
77 pm->IsOriginExperimentWash(), histogram)
78
79 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \
80 PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram)
81
82 #define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \
83 static uint8 recording_experiment = kNoExperiment; \
84 if (recording_experiment == kNoExperiment && experiment != kNoExperiment) \
85 recording_experiment = experiment; \
86 if (wash) { \
87 histogram; \
88 } else if (experiment != kNoExperiment && \
89 (origin != ORIGIN_LINK_REL_PRERENDER || \
90 experiment != recording_experiment)) { \
91 } else if (experiment != kNoExperiment) { \
92 histogram; \
93 } else if (origin == ORIGIN_OMNIBOX) { \
94 histogram; \
95 } else { \
96 histogram; \
97 } \
98 }
99
71 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { 100 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate {
72 public: 101 public:
73 OnCloseTabContentsDeleter(PrerenderManager* manager, 102 OnCloseTabContentsDeleter(PrerenderManager* manager,
74 TabContentsWrapper* tab) 103 TabContentsWrapper* tab)
75 : manager_(manager), 104 : manager_(manager),
76 tab_(tab) { 105 tab_(tab) {
77 tab_->tab_contents()->set_delegate(this); 106 tab_->tab_contents()->set_delegate(this);
78 } 107 }
79 108
80 virtual void CloseContents(TabContents* source) OVERRIDE { 109 virtual void CloseContents(TabContents* source) OVERRIDE {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || 146 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP ||
118 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; 147 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
119 } 148 }
120 149
121 // static 150 // static
122 bool PrerenderManager::IsControlGroup() { 151 bool PrerenderManager::IsControlGroup() {
123 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; 152 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
124 } 153 }
125 154
126 // static 155 // static
127 bool PrerenderManager::MaybeGetQueryStringBasedAliasURL(
128 const GURL& url, GURL* alias_url) {
129 DCHECK(alias_url);
130 url_parse::Parsed parsed;
131 url_parse::ParseStandardURL(url.spec().c_str(), url.spec().length(),
132 &parsed);
133 url_parse::Component query = parsed.query;
134 url_parse::Component key, value;
135 while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key,
136 &value)) {
137 if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "url", key.len))
138 continue;
139 // We found a url= query string component.
140 if (value.len < 1)
141 continue;
142 url_canon::RawCanonOutputW<1024> decoded_url;
143 url_util::DecodeURLEscapeSequences(url.spec().c_str() + value.begin,
144 value.len, &decoded_url);
145 GURL new_url(string16(decoded_url.data(), decoded_url.length()));
146 if (!new_url.is_empty() && new_url.is_valid()) {
147 *alias_url = new_url;
148 return true;
149 }
150 return false;
151 }
152 return false;
153 }
154
155 // static
156 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { 156 bool PrerenderManager::IsValidHttpMethod(const std::string& method) {
157 // method has been canonicalized to upper case at this point so we can just 157 // method has been canonicalized to upper case at this point so we can just
158 // compare them. 158 // compare them.
159 DCHECK_EQ(method, StringToUpperASCII(method)); 159 DCHECK_EQ(method, StringToUpperASCII(method));
160 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { 160 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) {
161 if (method.compare(kValidHttpMethods[i]) == 0) 161 if (method.compare(kValidHttpMethods[i]) == 0)
162 return true; 162 return true;
163 } 163 }
164 164
165 return false; 165 return false;
(...skipping 27 matching lines...) Expand all
193 GURL referrer_; 193 GURL referrer_;
194 Origin origin_; 194 Origin origin_;
195 }; 195 };
196 196
197 PrerenderManager::PrerenderManager(Profile* profile, 197 PrerenderManager::PrerenderManager(Profile* profile,
198 PrerenderTracker* prerender_tracker) 198 PrerenderTracker* prerender_tracker)
199 : enabled_(true), 199 : enabled_(true),
200 profile_(profile), 200 profile_(profile),
201 prerender_tracker_(prerender_tracker), 201 prerender_tracker_(prerender_tracker),
202 prerender_contents_factory_(PrerenderContents::CreateFactory()), 202 prerender_contents_factory_(PrerenderContents::CreateFactory()),
203 last_experiment_id_(kNoExperiment),
204 last_origin_(ORIGIN_LINK_REL_PRERENDER),
205 origin_experiment_wash_(false),
203 last_prerender_start_time_(GetCurrentTimeTicks() - 206 last_prerender_start_time_(GetCurrentTimeTicks() -
204 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), 207 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)),
205 runnable_method_factory_(this), 208 runnable_method_factory_(this),
206 prerender_history_(new PrerenderHistory(kHistoryLength)) { 209 prerender_history_(new PrerenderHistory(kHistoryLength)) {
207 // There are some assumptions that the PrerenderManager is on the UI thread. 210 // There are some assumptions that the PrerenderManager is on the UI thread.
208 // Any other checks simply make sure that the PrerenderManager is accessed on 211 // Any other checks simply make sure that the PrerenderManager is accessed on
209 // the same thread that it was created on. 212 // the same thread that it was created on.
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 } 214 }
212 215
(...skipping 26 matching lines...) Expand all
239 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL()); 242 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL());
240 } 243 }
241 244
242 bool PrerenderManager::AddPrerender( 245 bool PrerenderManager::AddPrerender(
243 Origin origin, 246 Origin origin,
244 const std::pair<int, int>& child_route_id_pair, 247 const std::pair<int, int>& child_route_id_pair,
245 const GURL& url_arg, 248 const GURL& url_arg,
246 const GURL& referrer) { 249 const GURL& referrer) {
247 DCHECK(CalledOnValidThread()); 250 DCHECK(CalledOnValidThread());
248 251
252 // Check if we are doing an experiment.
253 uint8 experiment = GetQueryStringBasedExperiment(url_arg);
254
255 // We need to update last_experiment_id_, last_origin_, and
256 // origin_experiment_wash_.
257 if (!WithinWindow()) {
258 // If we are outside a window, this is a fresh start and we are fine,
259 // and there is no mix.
260 origin_experiment_wash_ = false;
261 } else {
262 // If we are inside the last window, there is a mish mash of origins
263 // and experiments if either there was a mish mash before, or the current
264 // experiment/origin does not match the previous one.
265 if (experiment != last_experiment_id_ || origin != last_origin_)
266 origin_experiment_wash_ = true;
267 }
268
269 last_origin_ = origin;
270 last_experiment_id_ = experiment;
271
249 // If we observe multiple tags within the 30 second window, we will still 272 // If we observe multiple tags within the 30 second window, we will still
250 // reset the window to begin at the most recent occurrence, so that we will 273 // reset the window to begin at the most recent occurrence, so that we will
251 // always be in a window in the 30 seconds from each occurrence. 274 // always be in a window in the 30 seconds from each occurrence.
252 last_prerender_seen_time_ = GetCurrentTimeTicks(); 275 last_prerender_seen_time_ = GetCurrentTimeTicks();
253 276
254 // If the referring page is prerendering, defer the prerender. 277 // If the referring page is prerendering, defer the prerender.
255 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != 278 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) !=
256 prerender_list_.end()) { 279 prerender_list_.end()) {
257 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer); 280 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer);
258 return true; 281 return true;
259 } 282 }
260 283
261 DeleteOldEntries(); 284 DeleteOldEntries();
262 DeletePendingDeleteEntries(); 285 DeletePendingDeleteEntries();
263 286
264 GURL url = url_arg; 287 GURL url = url_arg;
265 GURL alias_url; 288 GURL alias_url;
266 if (IsControlGroup() && 289 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) {
267 PrerenderManager::MaybeGetQueryStringBasedAliasURL(
268 url, &alias_url)) {
269 url = alias_url; 290 url = alias_url;
270 } 291 }
271 292
272 if (FindEntry(url)) 293 if (FindEntry(url))
273 return false; 294 return false;
274 295
275 // Do not prerender if there are too many render processes, and we would 296 // Do not prerender if there are too many render processes, and we would
276 // have to use an existing one. We do not want prerendering to happen in 297 // have to use an existing one. We do not want prerendering to happen in
277 // a shared process, so that we can always reliably lower the CPU 298 // a shared process, so that we can always reliably lower the CPU
278 // priority for prerendering. 299 // priority for prerendering.
279 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns 300 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns
280 // true, so that case needs to be explicitly checked for. 301 // true, so that case needs to be explicitly checked for.
281 // TODO(tburkard): Figure out how to cancel prerendering in the opposite 302 // TODO(tburkard): Figure out how to cancel prerendering in the opposite
282 // case, when a new tab is added to a process used for prerendering. 303 // case, when a new tab is added to a process used for prerendering.
283 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && 304 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() &&
284 !RenderProcessHost::run_renderer_in_process()) { 305 !RenderProcessHost::run_renderer_in_process()) {
285 RecordFinalStatus(origin, FINAL_STATUS_TOO_MANY_PROCESSES); 306 RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
286 return false; 307 return false;
287 } 308 }
288 309
289 // Check if enough time has passed since the last prerender. 310 // Check if enough time has passed since the last prerender.
290 if (!DoesRateLimitAllowPrerender()) { 311 if (!DoesRateLimitAllowPrerender()) {
291 // Cancel the prerender. We could add it to the pending prerender list but 312 // Cancel the prerender. We could add it to the pending prerender list but
292 // this doesn't make sense as the next prerender request will be triggered 313 // this doesn't make sense as the next prerender request will be triggered
293 // by a navigation and is unlikely to be the same site. 314 // by a navigation and is unlikely to be the same site.
294 RecordFinalStatus(origin, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 315 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
295 return false; 316 return false;
296 } 317 }
297 318
298 RenderViewHost* source_render_view_host = NULL; 319 RenderViewHost* source_render_view_host = NULL;
299 // This test should fail only during unit tests. 320 // This test should fail only during unit tests.
300 if (child_route_id_pair.first != -1) { 321 if (child_route_id_pair.first != -1) {
301 source_render_view_host = 322 source_render_view_host =
302 RenderViewHost::FromID(child_route_id_pair.first, 323 RenderViewHost::FromID(child_route_id_pair.first,
303 child_route_id_pair.second); 324 child_route_id_pair.second);
304 // Don't prerender page if parent RenderViewHost no longer exists, or it has 325 // Don't prerender page if parent RenderViewHost no longer exists, or it has
305 // no view. The latter should only happen when the RenderView has closed. 326 // no view. The latter should only happen when the RenderView has closed.
306 if (!source_render_view_host || !source_render_view_host->view()) { 327 if (!source_render_view_host || !source_render_view_host->view()) {
307 RecordFinalStatus(origin, FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED); 328 RecordFinalStatus(origin, experiment,
329 FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED);
308 return false; 330 return false;
309 } 331 }
310 } 332 }
311 333
312 PrerenderContents* prerender_contents = 334 PrerenderContents* prerender_contents =
313 CreatePrerenderContents(url, referrer, origin); 335 CreatePrerenderContents(url, referrer, origin, experiment);
314 if (!prerender_contents || !prerender_contents->Init()) 336 if (!prerender_contents || !prerender_contents->Init())
315 return false; 337 return false;
316 338
317 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 339 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
318 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 340 PrerenderContentsData data(prerender_contents, GetCurrentTime());
319 341
320 prerender_list_.push_back(data); 342 prerender_list_.push_back(data);
321 343
322 if (IsControlGroup()) { 344 if (IsControlGroup()) {
323 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); 345 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 // Try to set the prerendered page as used, so any subsequent attempts to 495 // Try to set the prerendered page as used, so any subsequent attempts to
474 // cancel on other threads will fail. If this fails because the prerender 496 // cancel on other threads will fail. If this fails because the prerender
475 // was already cancelled, possibly on another thread, fail. 497 // was already cancelled, possibly on another thread, fail.
476 if (!prerender_tracker_->TryUse(child_id, route_id)) 498 if (!prerender_tracker_->TryUse(child_id, route_id))
477 return false; 499 return false;
478 500
479 if (!prerender_contents->load_start_time().is_null()) 501 if (!prerender_contents->load_start_time().is_null())
480 RecordTimeUntilUsed(GetCurrentTimeTicks() - 502 RecordTimeUntilUsed(GetCurrentTimeTicks() -
481 prerender_contents->load_start_time()); 503 prerender_contents->load_start_time());
482 504
483 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 505 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS(
484 ++prerenders_per_session_count_); 506 GetDefaultHistogramName("PrerendersPerSessionCount"),
507 ++prerenders_per_session_count_));
485 prerender_contents->set_final_status(FINAL_STATUS_USED); 508 prerender_contents->set_final_status(FINAL_STATUS_USED);
486 509
487 RenderViewHost* render_view_host = 510 RenderViewHost* render_view_host =
488 prerender_contents->prerender_contents()->render_view_host(); 511 prerender_contents->prerender_contents()->render_view_host();
489 DCHECK(render_view_host); 512 DCHECK(render_view_host);
490 render_view_host->Send( 513 render_view_host->Send(
491 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 514 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
492 515
493 TabContentsWrapper* new_tab_contents = 516 TabContentsWrapper* new_tab_contents =
494 prerender_contents->ReleasePrerenderContents(); 517 prerender_contents->ReleasePrerenderContents();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 607
585 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const { 608 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const {
586 DCHECK(CalledOnValidThread()); 609 DCHECK(CalledOnValidThread());
587 base::Time now = GetCurrentTime(); 610 base::Time now = GetCurrentTime();
588 return (now - start < config_.max_age); 611 return (now - start < config_.max_age);
589 } 612 }
590 613
591 PrerenderContents* PrerenderManager::CreatePrerenderContents( 614 PrerenderContents* PrerenderManager::CreatePrerenderContents(
592 const GURL& url, 615 const GURL& url,
593 const GURL& referrer, 616 const GURL& referrer,
594 Origin origin) { 617 Origin origin,
618 uint8 experiment_id) {
595 DCHECK(CalledOnValidThread()); 619 DCHECK(CalledOnValidThread());
596 return prerender_contents_factory_->CreatePrerenderContents( 620 return prerender_contents_factory_->CreatePrerenderContents(
597 this, prerender_tracker_, profile_, url, referrer, origin); 621 this, prerender_tracker_, profile_, url, referrer, origin, experiment_id);
598 } 622 }
599 623
600 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const { 624 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const {
601 DCHECK(CalledOnValidThread()); 625 DCHECK(CalledOnValidThread());
602 for (std::list<PrerenderContents*>::const_iterator it = 626 for (std::list<PrerenderContents*>::const_iterator it =
603 pending_delete_list_.begin(); 627 pending_delete_list_.begin();
604 it != pending_delete_list_.end(); 628 it != pending_delete_list_.end();
605 ++it) { 629 ++it) {
606 if (*it == entry) 630 if (*it == entry)
607 return true; 631 return true;
608 } 632 }
609 633
610 return false; 634 return false;
611 } 635 }
612 636
613 void PrerenderManager::DeletePendingDeleteEntries() { 637 void PrerenderManager::DeletePendingDeleteEntries() {
614 while (!pending_delete_list_.empty()) { 638 while (!pending_delete_list_.empty()) {
615 PrerenderContents* contents = pending_delete_list_.front(); 639 PrerenderContents* contents = pending_delete_list_.front();
616 pending_delete_list_.pop_front(); 640 pending_delete_list_.pop_front();
617 AddToHistory(contents); 641 AddToHistory(contents);
618 delete contents; 642 delete contents;
619 } 643 }
620 } 644 }
621 645
622 // Helper macro for histograms. 646 // Helper macro for histograms.
623 #define RECORD_PLT(tag, perceived_page_load_time) { \ 647 #define RECORD_PLT(tag, perceived_page_load_time) { \
648 PREFIXED_HISTOGRAM_PRERENDER_MANAGER(prerender_manager, \
624 UMA_HISTOGRAM_CUSTOM_TIMES( \ 649 UMA_HISTOGRAM_CUSTOM_TIMES( \
625 base::FieldTrial::MakeName(std::string("Prerender.") + tag, \ 650 base::FieldTrial::MakeName( \
626 "Prefetch"), \ 651 prerender_manager->GetDefaultHistogramName(tag), "Prefetch"), \
627 perceived_page_load_time, \ 652 perceived_page_load_time, \
628 base::TimeDelta::FromMilliseconds(10), \ 653 base::TimeDelta::FromMilliseconds(10), \
629 base::TimeDelta::FromSeconds(60), \ 654 base::TimeDelta::FromSeconds(60), \
630 100); \ 655 100)); \
631 } 656 }
632 657
633 // static 658 // static
634 void PrerenderManager::RecordPerceivedPageLoadTime( 659 void PrerenderManager::RecordPerceivedPageLoadTime(
635 base::TimeDelta perceived_page_load_time, 660 base::TimeDelta perceived_page_load_time,
636 TabContents* tab_contents) { 661 TabContents* tab_contents) {
637 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
638 PrerenderManager* prerender_manager = 663 PrerenderManager* prerender_manager =
639 tab_contents->profile()->GetPrerenderManager(); 664 tab_contents->profile()->GetPrerenderManager();
640 if (!prerender_manager) 665 if (!prerender_manager)
641 return; 666 return;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 return false; 744 return false;
720 base::TimeDelta elapsed_time = 745 base::TimeDelta elapsed_time =
721 base::TimeTicks::Now() - last_prerender_seen_time_; 746 base::TimeTicks::Now() - last_prerender_seen_time_;
722 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds); 747 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds);
723 } 748 }
724 749
725 bool PrerenderManager::DoesRateLimitAllowPrerender() const { 750 bool PrerenderManager::DoesRateLimitAllowPrerender() const {
726 DCHECK(CalledOnValidThread()); 751 DCHECK(CalledOnValidThread());
727 base::TimeDelta elapsed_time = 752 base::TimeDelta elapsed_time =
728 GetCurrentTimeTicks() - last_prerender_start_time_; 753 GetCurrentTimeTicks() - last_prerender_start_time_;
729 UMA_HISTOGRAM_TIMES("Prerender.TimeBetweenPrerenderRequests", 754 PREFIXED_HISTOGRAM(
730 elapsed_time); 755 UMA_HISTOGRAM_TIMES(
756 GetDefaultHistogramName("TimeBetweenPrerenderRequests"),
757 elapsed_time));
731 if (!config_.rate_limit_enabled) 758 if (!config_.rate_limit_enabled)
732 return true; 759 return true;
733 return elapsed_time > 760 return elapsed_time >
734 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); 761 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs);
735 } 762 }
736 763
737 void PrerenderManager::StartSchedulingPeriodicCleanups() { 764 void PrerenderManager::StartSchedulingPeriodicCleanups() {
738 DCHECK(CalledOnValidThread()); 765 DCHECK(CalledOnValidThread());
739 if (repeating_timer_.IsRunning()) 766 if (repeating_timer_.IsRunning())
740 return; 767 return;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 while (!prerender_list_.empty()) { 987 while (!prerender_list_.empty()) {
961 PrerenderContentsData data = prerender_list_.front(); 988 PrerenderContentsData data = prerender_list_.front();
962 prerender_list_.pop_front(); 989 prerender_list_.pop_front();
963 data.contents_->Destroy(final_status); 990 data.contents_->Destroy(final_status);
964 } 991 }
965 DeletePendingDeleteEntries(); 992 DeletePendingDeleteEntries();
966 } 993 }
967 994
968 void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) { 995 void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) {
969 DCHECK(CalledOnValidThread()); 996 DCHECK(CalledOnValidThread());
970 UMA_HISTOGRAM_CUSTOM_TIMES( 997 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES(
971 "Prerender.TimeUntilUsed", 998 GetDefaultHistogramName("TimeUntilUsed"),
972 time_until_used, 999 time_until_used,
973 base::TimeDelta::FromMilliseconds(10), 1000 base::TimeDelta::FromMilliseconds(10),
974 config_.max_age, 1001 config_.max_age,
975 50); 1002 50));
1003 }
1004
1005 void PrerenderManager::RecordFinalStatus(Origin origin,
1006 uint8 experiment_id,
1007 FinalStatus final_status) const {
1008 DCHECK(final_status != FINAL_STATUS_MAX);
1009 // FINAL_STATUS_CONTROL_GROUP indicates that the PrerenderContents
1010 // was created only to measure "would-have-been-prerendered" for
1011 // control group measurements. Don't pollute data with it.
1012 if (PrerenderManager::IsControlGroup() ||
1013 final_status == FINAL_STATUS_CONTROL_GROUP)
1014 return;
1015 PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id,
1016 UMA_HISTOGRAM_ENUMERATION(
1017 GetHistogramName(origin, experiment_id, "FinalStatus"),
1018 final_status,
1019 FINAL_STATUS_MAX));
1020 }
1021
1022 std::string PrerenderManager::ComposeHistogramName(
1023 const std::string& prefix_type,
1024 const std::string& name) const {
1025 if (prefix_type.empty())
1026 return std::string("Prerender.") + name;
1027 return std::string("Prerender.") + prefix_type + std::string("_") + name;
1028 }
1029
1030 std::string PrerenderManager::GetHistogramName(Origin origin,
1031 uint8 experiment_id,
1032 const std::string& name) const {
1033 switch (origin) {
1034 case ORIGIN_OMNIBOX:
1035 if (experiment_id != kNoExperiment)
1036 return ComposeHistogramName("wash", name);
1037 return ComposeHistogramName("omnibox", name);
1038 case ORIGIN_LINK_REL_PRERENDER:
1039 if (experiment_id == kNoExperiment)
1040 return ComposeHistogramName("", name);
1041 return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'),
1042 name);
1043 default:
1044 NOTREACHED();
1045 break;
1046 };
1047
1048 // Dummy return value to make the compiler happy.
1049 NOTREACHED();
1050 return ComposeHistogramName("wash", name);
1051 }
1052
1053 std::string PrerenderManager::GetDefaultHistogramName(
1054 const std::string& name) const {
1055 if (!WithinWindow())
1056 return ComposeHistogramName("", name);
1057 if (origin_experiment_wash_)
1058 return ComposeHistogramName("wash", name);
1059 return GetHistogramName(last_origin_, last_experiment_id_, name);
1060 }
1061
1062 uint8 PrerenderManager::GetCurrentExperimentId() const {
1063 if (!WithinWindow())
1064 return kNoExperiment;
1065 return last_experiment_id_;
1066 }
1067
1068 Origin PrerenderManager::GetCurrentOrigin() const {
1069 if (!WithinWindow())
1070 return ORIGIN_LINK_REL_PRERENDER;
1071 return last_origin_;
1072 }
1073
1074 bool PrerenderManager::IsOriginExperimentWash() const {
1075 if (!WithinWindow())
1076 return false;
1077 return origin_experiment_wash_;
976 } 1078 }
977 1079
978 } // namespace prerender 1080 } // namespace prerender
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | chrome/browser/prerender/prerender_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698