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

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 // Default maximum permitted elements to prerender. 42 // Default maximum permitted elements to prerender.
45 const unsigned int kDefaultMaxPrerenderElements = 1; 43 const unsigned int kDefaultMaxPrerenderElements = 1;
46 44
47 // Default maximum amount of private memory that may be used per 45 // Default maximum amount of private memory that may be used per
48 // PrerenderContents, in MB. 46 // PrerenderContents, in MB.
(...skipping 22 matching lines...) Expand all
71 "OPTIONS", 69 "OPTIONS",
72 "POST", 70 "POST",
73 "TRACE", 71 "TRACE",
74 }; 72 };
75 73
76 // Length of prerender history, for display in chrome://net-internals 74 // Length of prerender history, for display in chrome://net-internals
77 const int kHistoryLength = 100; 75 const int kHistoryLength = 100;
78 76
79 } // namespace 77 } // namespace
80 78
79 // Helper macros for experiment-based and origin-based histogram reporting.
80 #define PREFIXED_HISTOGRAM(histogram) \
81 PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \
82 IsOriginExperimentWash(), histogram)
83
84 #define PREFIXED_HISTOGRAM_PRERENDER_MANAGER(pm, histogram) \
85 PREFIXED_HISTOGRAM_INTERNAL(pm->GetCurrentOrigin(), \
86 pm->GetCurrentExperimentId(), \
87 pm->IsOriginExperimentWash(), histogram)
88
89 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \
90 PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram)
91
92 #define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \
93 static uint8 experiment_id = kNoExperiment; \
94 if (experiment_id == kNoExperiment && experiment != kNoExperiment) \
95 experiment_id = experiment; \
96 if (wash || \
97 (experiment != kNoExperiment && (origin != ORIGIN_LINK_REL_PRERENDER || \
98 experiment != experiment_id))) { \
99 histogram; \
100 } else if (experiment != kNoExperiment) { \
101 histogram; \
102 } else if (origin == ORIGIN_OMNIBOX) { \
103 histogram; \
104 } else { \
105 histogram; \
106 } \
107 }
108
81 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { 109 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate {
82 public: 110 public:
83 OnCloseTabContentsDeleter(PrerenderManager* manager, 111 OnCloseTabContentsDeleter(PrerenderManager* manager,
84 TabContentsWrapper* tab) 112 TabContentsWrapper* tab)
85 : manager_(manager), 113 : manager_(manager),
86 tab_(tab) { 114 tab_(tab) {
87 tab_->tab_contents()->set_delegate(this); 115 tab_->tab_contents()->set_delegate(this);
88 } 116 }
89 117
90 virtual void CloseContents(TabContents* source) OVERRIDE { 118 virtual void CloseContents(TabContents* source) OVERRIDE {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || 168 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP ||
141 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; 169 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
142 } 170 }
143 171
144 // static 172 // static
145 bool PrerenderManager::IsControlGroup() { 173 bool PrerenderManager::IsControlGroup() {
146 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; 174 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
147 } 175 }
148 176
149 // static 177 // static
150 bool PrerenderManager::MaybeGetQueryStringBasedAliasURL(
151 const GURL& url, GURL* alias_url) {
152 DCHECK(alias_url);
153 url_parse::Parsed parsed;
154 url_parse::ParseStandardURL(url.spec().c_str(), url.spec().length(),
155 &parsed);
156 url_parse::Component query = parsed.query;
157 url_parse::Component key, value;
158 while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key,
159 &value)) {
160 if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "url", key.len))
161 continue;
162 // We found a url= query string component.
163 if (value.len < 1)
164 continue;
165 url_canon::RawCanonOutputW<1024> decoded_url;
166 url_util::DecodeURLEscapeSequences(url.spec().c_str() + value.begin,
167 value.len, &decoded_url);
168 GURL new_url(string16(decoded_url.data(), decoded_url.length()));
169 if (!new_url.is_empty() && new_url.is_valid()) {
170 *alias_url = new_url;
171 return true;
172 }
173 return false;
174 }
175 return false;
176 }
177
178 // static
179 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { 178 bool PrerenderManager::IsValidHttpMethod(const std::string& method) {
180 // method has been canonicalized to upper case at this point so we can just 179 // method has been canonicalized to upper case at this point so we can just
181 // compare them. 180 // compare them.
182 DCHECK_EQ(method, StringToUpperASCII(method)); 181 DCHECK_EQ(method, StringToUpperASCII(method));
183 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { 182 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) {
184 if (method.compare(kValidHttpMethods[i]) == 0) 183 if (method.compare(kValidHttpMethods[i]) == 0)
185 return true; 184 return true;
186 } 185 }
187 186
188 return false; 187 return false;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 PrerenderTracker* prerender_tracker) 221 PrerenderTracker* prerender_tracker)
223 : rate_limit_enabled_(true), 222 : rate_limit_enabled_(true),
224 enabled_(true), 223 enabled_(true),
225 profile_(profile), 224 profile_(profile),
226 prerender_tracker_(prerender_tracker), 225 prerender_tracker_(prerender_tracker),
227 max_prerender_age_(base::TimeDelta::FromSeconds( 226 max_prerender_age_(base::TimeDelta::FromSeconds(
228 kDefaultMaxPrerenderAgeSeconds)), 227 kDefaultMaxPrerenderAgeSeconds)),
229 max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB), 228 max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB),
230 max_elements_(kDefaultMaxPrerenderElements), 229 max_elements_(kDefaultMaxPrerenderElements),
231 prerender_contents_factory_(PrerenderContents::CreateFactory()), 230 prerender_contents_factory_(PrerenderContents::CreateFactory()),
231 last_experiment_id_(kNoExperiment),
232 last_origin_(ORIGIN_LINK_REL_PRERENDER),
233 origin_experiment_wash_(false),
232 last_prerender_start_time_(GetCurrentTimeTicks() - 234 last_prerender_start_time_(GetCurrentTimeTicks() -
233 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), 235 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)),
234 runnable_method_factory_(this), 236 runnable_method_factory_(this),
235 prerender_history_(new PrerenderHistory(kHistoryLength)) { 237 prerender_history_(new PrerenderHistory(kHistoryLength)) {
236 // There are some assumptions that the PrerenderManager is on the UI thread. 238 // There are some assumptions that the PrerenderManager is on the UI thread.
237 // Any other checks simply make sure that the PrerenderManager is accessed on 239 // Any other checks simply make sure that the PrerenderManager is accessed on
238 // the same thread that it was created on. 240 // the same thread that it was created on.
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
240 } 242 }
241 243
(...skipping 26 matching lines...) Expand all
268 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL()); 270 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL());
269 } 271 }
270 272
271 bool PrerenderManager::AddPrerender( 273 bool PrerenderManager::AddPrerender(
272 Origin origin, 274 Origin origin,
273 const std::pair<int, int>& child_route_id_pair, 275 const std::pair<int, int>& child_route_id_pair,
274 const GURL& url_arg, 276 const GURL& url_arg,
275 const GURL& referrer) { 277 const GURL& referrer) {
276 DCHECK(CalledOnValidThread()); 278 DCHECK(CalledOnValidThread());
277 279
280 // Check if we are doing an experiment.
281 uint8 experiment = GetQueryStringBasedExperiment(url_arg);
282
283 // We need to update last_experiment_id_, last_origin_, and
284 // origin_experiment_wash_.
285 if (!WithinWindow()) {
286 // If we are outside a window, this is a fresh start and we are fine,
287 // and there is no mix.
288 origin_experiment_wash_ = false;
289 } else {
290 // If we are inside the last window, there is a mish mash of origins
291 // and experiments if either there was a mish mash before, or the current
292 // experiment/origin does not match the previous one.
293 if (experiment != last_experiment_id_ || origin != last_origin_)
294 origin_experiment_wash_ = true;
295 }
296
297 last_origin_ = origin;
298 last_experiment_id_ = experiment;
299
278 // If we observe multiple tags within the 30 second window, we will still 300 // If we observe multiple tags within the 30 second window, we will still
279 // reset the window to begin at the most recent occurrence, so that we will 301 // reset the window to begin at the most recent occurrence, so that we will
280 // always be in a window in the 30 seconds from each occurrence. 302 // always be in a window in the 30 seconds from each occurrence.
281 last_prerender_seen_time_ = GetCurrentTimeTicks(); 303 last_prerender_seen_time_ = GetCurrentTimeTicks();
282 304
283 // If the referring page is prerendering, defer the prerender. 305 // If the referring page is prerendering, defer the prerender.
284 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != 306 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) !=
285 prerender_list_.end()) { 307 prerender_list_.end()) {
286 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer); 308 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer);
287 return true; 309 return true;
288 } 310 }
289 311
290 DeleteOldEntries(); 312 DeleteOldEntries();
291 DeletePendingDeleteEntries(); 313 DeletePendingDeleteEntries();
292 314
293 GURL url = url_arg; 315 GURL url = url_arg;
294 GURL alias_url; 316 GURL alias_url;
295 if (IsControlGroup() && 317 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) {
296 PrerenderManager::MaybeGetQueryStringBasedAliasURL(
297 url, &alias_url)) {
298 url = alias_url; 318 url = alias_url;
299 } 319 }
300 320
301 if (FindEntry(url)) 321 if (FindEntry(url))
302 return false; 322 return false;
303 323
304 // Do not prerender if there are too many render processes, and we would 324 // Do not prerender if there are too many render processes, and we would
305 // have to use an existing one. We do not want prerendering to happen in 325 // have to use an existing one. We do not want prerendering to happen in
306 // a shared process, so that we can always reliably lower the CPU 326 // a shared process, so that we can always reliably lower the CPU
307 // priority for prerendering. 327 // priority for prerendering.
308 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns 328 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns
309 // true, so that case needs to be explicitly checked for. 329 // true, so that case needs to be explicitly checked for.
310 // TODO(tburkard): Figure out how to cancel prerendering in the opposite 330 // TODO(tburkard): Figure out how to cancel prerendering in the opposite
311 // case, when a new tab is added to a process used for prerendering. 331 // case, when a new tab is added to a process used for prerendering.
312 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && 332 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() &&
313 !RenderProcessHost::run_renderer_in_process()) { 333 !RenderProcessHost::run_renderer_in_process()) {
314 RecordFinalStatus(origin, FINAL_STATUS_TOO_MANY_PROCESSES); 334 RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
315 return false; 335 return false;
316 } 336 }
317 337
318 // Check if enough time has passed since the last prerender. 338 // Check if enough time has passed since the last prerender.
319 if (!DoesRateLimitAllowPrerender()) { 339 if (!DoesRateLimitAllowPrerender()) {
320 // Cancel the prerender. We could add it to the pending prerender list but 340 // Cancel the prerender. We could add it to the pending prerender list but
321 // this doesn't make sense as the next prerender request will be triggered 341 // this doesn't make sense as the next prerender request will be triggered
322 // by a navigation and is unlikely to be the same site. 342 // by a navigation and is unlikely to be the same site.
323 RecordFinalStatus(origin, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 343 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
324 return false; 344 return false;
325 } 345 }
326 346
327 RenderViewHost* source_render_view_host = NULL; 347 RenderViewHost* source_render_view_host = NULL;
328 // This test should fail only during unit tests. 348 // This test should fail only during unit tests.
329 if (child_route_id_pair.first != -1) { 349 if (child_route_id_pair.first != -1) {
330 source_render_view_host = 350 source_render_view_host =
331 RenderViewHost::FromID(child_route_id_pair.first, 351 RenderViewHost::FromID(child_route_id_pair.first,
332 child_route_id_pair.second); 352 child_route_id_pair.second);
333 // Don't prerender page if parent RenderViewHost no longer exists, or it has 353 // Don't prerender page if parent RenderViewHost no longer exists, or it has
334 // no view. The latter should only happen when the RenderView has closed. 354 // no view. The latter should only happen when the RenderView has closed.
335 if (!source_render_view_host || !source_render_view_host->view()) { 355 if (!source_render_view_host || !source_render_view_host->view()) {
336 RecordFinalStatus(origin, FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED); 356 RecordFinalStatus(origin, experiment,
357 FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED);
337 return false; 358 return false;
338 } 359 }
339 } 360 }
340 361
341 PrerenderContents* prerender_contents = 362 PrerenderContents* prerender_contents =
342 CreatePrerenderContents(url, referrer, origin); 363 CreatePrerenderContents(url, referrer, origin, experiment);
343 if (!prerender_contents || !prerender_contents->Init()) 364 if (!prerender_contents || !prerender_contents->Init())
344 return false; 365 return false;
345 366
346 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 367 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
347 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 368 PrerenderContentsData data(prerender_contents, GetCurrentTime());
348 369
349 prerender_list_.push_back(data); 370 prerender_list_.push_back(data);
350 371
351 if (IsControlGroup()) { 372 if (IsControlGroup()) {
352 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); 373 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // Try to set the prerendered page as used, so any subsequent attempts to 523 // Try to set the prerendered page as used, so any subsequent attempts to
503 // cancel on other threads will fail. If this fails because the prerender 524 // cancel on other threads will fail. If this fails because the prerender
504 // was already cancelled, possibly on another thread, fail. 525 // was already cancelled, possibly on another thread, fail.
505 if (!prerender_tracker_->TryUse(child_id, route_id)) 526 if (!prerender_tracker_->TryUse(child_id, route_id))
506 return false; 527 return false;
507 528
508 if (!prerender_contents->load_start_time().is_null()) 529 if (!prerender_contents->load_start_time().is_null())
509 RecordTimeUntilUsed(GetCurrentTimeTicks() - 530 RecordTimeUntilUsed(GetCurrentTimeTicks() -
510 prerender_contents->load_start_time()); 531 prerender_contents->load_start_time());
511 532
512 UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount", 533 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS(
513 ++prerenders_per_session_count_); 534 GetDefaultHistogramName("Prerender.PrerendersPerSessionCount"),
535 ++prerenders_per_session_count_));
514 prerender_contents->set_final_status(FINAL_STATUS_USED); 536 prerender_contents->set_final_status(FINAL_STATUS_USED);
515 537
516 RenderViewHost* render_view_host = 538 RenderViewHost* render_view_host =
517 prerender_contents->prerender_contents()->render_view_host(); 539 prerender_contents->prerender_contents()->render_view_host();
518 DCHECK(render_view_host); 540 DCHECK(render_view_host);
519 render_view_host->Send( 541 render_view_host->Send(
520 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); 542 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
521 543
522 TabContentsWrapper* new_tab_contents = 544 TabContentsWrapper* new_tab_contents =
523 prerender_contents->ReleasePrerenderContents(); 545 prerender_contents->ReleasePrerenderContents();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 635
614 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const { 636 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const {
615 DCHECK(CalledOnValidThread()); 637 DCHECK(CalledOnValidThread());
616 base::Time now = GetCurrentTime(); 638 base::Time now = GetCurrentTime();
617 return (now - start < max_prerender_age_); 639 return (now - start < max_prerender_age_);
618 } 640 }
619 641
620 PrerenderContents* PrerenderManager::CreatePrerenderContents( 642 PrerenderContents* PrerenderManager::CreatePrerenderContents(
621 const GURL& url, 643 const GURL& url,
622 const GURL& referrer, 644 const GURL& referrer,
623 Origin origin) { 645 Origin origin,
646 uint8 experiment_id) {
624 DCHECK(CalledOnValidThread()); 647 DCHECK(CalledOnValidThread());
625 return prerender_contents_factory_->CreatePrerenderContents( 648 return prerender_contents_factory_->CreatePrerenderContents(
626 this, prerender_tracker_, profile_, url, referrer, origin); 649 this, prerender_tracker_, profile_, url, referrer, origin, experiment_id);
627 } 650 }
628 651
629 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const { 652 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const {
630 DCHECK(CalledOnValidThread()); 653 DCHECK(CalledOnValidThread());
631 for (std::list<PrerenderContents*>::const_iterator it = 654 for (std::list<PrerenderContents*>::const_iterator it =
632 pending_delete_list_.begin(); 655 pending_delete_list_.begin();
633 it != pending_delete_list_.end(); 656 it != pending_delete_list_.end();
634 ++it) { 657 ++it) {
635 if (*it == entry) 658 if (*it == entry)
636 return true; 659 return true;
637 } 660 }
638 661
639 return false; 662 return false;
640 } 663 }
641 664
642 void PrerenderManager::DeletePendingDeleteEntries() { 665 void PrerenderManager::DeletePendingDeleteEntries() {
643 while (!pending_delete_list_.empty()) { 666 while (!pending_delete_list_.empty()) {
644 PrerenderContents* contents = pending_delete_list_.front(); 667 PrerenderContents* contents = pending_delete_list_.front();
645 pending_delete_list_.pop_front(); 668 pending_delete_list_.pop_front();
646 AddToHistory(contents); 669 AddToHistory(contents);
647 delete contents; 670 delete contents;
648 } 671 }
649 } 672 }
650 673
651 // Helper macro for histograms. 674 // Helper macro for histograms.
652 #define RECORD_PLT(tag, perceived_page_load_time) { \ 675 #define RECORD_PLT(tag, perceived_page_load_time) { \
676 PREFIXED_HISTOGRAM_PRERENDER_MANAGER(prerender_manager, \
653 UMA_HISTOGRAM_CUSTOM_TIMES( \ 677 UMA_HISTOGRAM_CUSTOM_TIMES( \
654 base::FieldTrial::MakeName(std::string("Prerender.") + tag, \ 678 base::FieldTrial::MakeName( \
655 "Prefetch"), \ 679 prerender_manager->GetDefaultHistogramName(tag), "Prefetch"), \
656 perceived_page_load_time, \ 680 perceived_page_load_time, \
657 base::TimeDelta::FromMilliseconds(10), \ 681 base::TimeDelta::FromMilliseconds(10), \
658 base::TimeDelta::FromSeconds(60), \ 682 base::TimeDelta::FromSeconds(60), \
659 100); \ 683 100)); \
660 } 684 }
661 685
662 // static 686 // static
663 void PrerenderManager::RecordPerceivedPageLoadTime( 687 void PrerenderManager::RecordPerceivedPageLoadTime(
664 base::TimeDelta perceived_page_load_time, 688 base::TimeDelta perceived_page_load_time,
665 TabContents* tab_contents) { 689 TabContents* tab_contents) {
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
667 PrerenderManager* prerender_manager = 691 PrerenderManager* prerender_manager =
668 tab_contents->profile()->GetPrerenderManager(); 692 tab_contents->profile()->GetPrerenderManager();
669 if (!prerender_manager) 693 if (!prerender_manager)
670 return; 694 return;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 return false; 802 return false;
779 base::TimeDelta elapsed_time = 803 base::TimeDelta elapsed_time =
780 base::TimeTicks::Now() - last_prerender_seen_time_; 804 base::TimeTicks::Now() - last_prerender_seen_time_;
781 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds); 805 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds);
782 } 806 }
783 807
784 bool PrerenderManager::DoesRateLimitAllowPrerender() const { 808 bool PrerenderManager::DoesRateLimitAllowPrerender() const {
785 DCHECK(CalledOnValidThread()); 809 DCHECK(CalledOnValidThread());
786 base::TimeDelta elapsed_time = 810 base::TimeDelta elapsed_time =
787 GetCurrentTimeTicks() - last_prerender_start_time_; 811 GetCurrentTimeTicks() - last_prerender_start_time_;
788 UMA_HISTOGRAM_TIMES("Prerender.TimeBetweenPrerenderRequests", 812 PREFIXED_HISTOGRAM(
789 elapsed_time); 813 UMA_HISTOGRAM_TIMES(
814 GetDefaultHistogramName("Prerender.TimeBetweenPrerenderRequests"),
815 elapsed_time));
790 if (!rate_limit_enabled_) 816 if (!rate_limit_enabled_)
791 return true; 817 return true;
792 return elapsed_time > 818 return elapsed_time >
793 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); 819 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs);
794 } 820 }
795 821
796 void PrerenderManager::StartSchedulingPeriodicCleanups() { 822 void PrerenderManager::StartSchedulingPeriodicCleanups() {
797 DCHECK(CalledOnValidThread()); 823 DCHECK(CalledOnValidThread());
798 if (repeating_timer_.IsRunning()) 824 if (repeating_timer_.IsRunning())
799 return; 825 return;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 while (!prerender_list_.empty()) { 1045 while (!prerender_list_.empty()) {
1020 PrerenderContentsData data = prerender_list_.front(); 1046 PrerenderContentsData data = prerender_list_.front();
1021 prerender_list_.pop_front(); 1047 prerender_list_.pop_front();
1022 data.contents_->Destroy(final_status); 1048 data.contents_->Destroy(final_status);
1023 } 1049 }
1024 DeletePendingDeleteEntries(); 1050 DeletePendingDeleteEntries();
1025 } 1051 }
1026 1052
1027 void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) { 1053 void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) {
1028 DCHECK(CalledOnValidThread()); 1054 DCHECK(CalledOnValidThread());
1029 UMA_HISTOGRAM_CUSTOM_TIMES( 1055 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES(
1030 "Prerender.TimeUntilUsed", 1056 GetDefaultHistogramName("Prerender.TimeUntilUsed"),
1031 time_until_used, 1057 time_until_used,
1032 base::TimeDelta::FromMilliseconds(10), 1058 base::TimeDelta::FromMilliseconds(10),
1033 base::TimeDelta::FromSeconds(kDefaultMaxPrerenderAgeSeconds), 1059 base::TimeDelta::FromSeconds(kDefaultMaxPrerenderAgeSeconds),
1034 50); 1060 50));
1061 }
1062
1063 void PrerenderManager::RecordFinalStatus(Origin origin,
1064 uint8 experiment_id,
1065 FinalStatus final_status) const {
1066 DCHECK(final_status != FINAL_STATUS_MAX);
1067 // FINAL_STATUS_CONTROL_GROUP indicates that the PrerenderContents
1068 // was created only to measure "would-have-been-prerendered" for
1069 // control group measurements. Don't pollute data with it.
1070 if (PrerenderManager::IsControlGroup() ||
1071 final_status == FINAL_STATUS_CONTROL_GROUP)
1072 return;
1073 PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id,
1074 UMA_HISTOGRAM_ENUMERATION(
1075 GetHistogramName(origin, experiment_id, "FinalStatus"),
1076 final_status,
1077 FINAL_STATUS_MAX));
1078 }
1079
1080 std::string PrerenderManager::ComposeHistogramName(
1081 const std::string& prefix_type,
1082 const std::string& name) const {
1083 if (prefix_type.empty())
1084 return std::string("Prerender.") + name;
1085 return std::string("Prerender.") + prefix_type + std::string("_") + name;
1086 }
1087
1088 std::string PrerenderManager::GetHistogramName(Origin origin,
1089 uint8 experiment_id,
1090 const std::string& name) const {
1091 switch (origin) {
1092 case ORIGIN_OMNIBOX:
1093 if (experiment_id != kNoExperiment)
1094 return ComposeHistogramName("wash", name);
1095 return ComposeHistogramName("omnibox", name);
1096 case ORIGIN_LINK_REL_PRERENDER:
1097 if (experiment_id == kNoExperiment)
1098 return ComposeHistogramName("", name);
1099 return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'),
1100 name);
1101 default:
1102 NOTREACHED();
1103 break;
1104 };
1105
1106 // Dummy return value to make the compiler happy.
1107 NOTREACHED();
1108 return ComposeHistogramName("wash", name);
1109 }
1110
1111 std::string PrerenderManager::GetDefaultHistogramName(
1112 const std::string& name) const {
1113 if (!WithinWindow())
1114 return ComposeHistogramName("", name);
1115 if (origin_experiment_wash_)
1116 return ComposeHistogramName("wash", name);
1117 return GetHistogramName(last_origin_, last_experiment_id_, name);
1118 }
1119
1120 uint8 PrerenderManager::GetCurrentExperimentId() const {
1121 if (!WithinWindow())
1122 return kNoExperiment;
1123 return last_experiment_id_;
1124 }
1125
1126 Origin PrerenderManager::GetCurrentOrigin() const {
1127 if (!WithinWindow())
1128 return ORIGIN_LINK_REL_PRERENDER;
1129 return last_origin_;
1130 }
1131
1132 bool PrerenderManager::IsOriginExperimentWash() const {
1133 if (!WithinWindow())
1134 return false;
1135 return origin_experiment_wash_;
1035 } 1136 }
1036 1137
1037 } // namespace prerender 1138 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698