OLD | NEW |
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" | |
12 #include "base/metrics/histogram.h" | |
13 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/string_util.h" |
14 #include "base/time.h" | 13 #include "base/time.h" |
15 #include "base/values.h" | 14 #include "base/values.h" |
16 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
17 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
18 #include "chrome/browser/favicon/favicon_tab_helper.h" | 17 #include "chrome/browser/favicon/favicon_tab_helper.h" |
19 #include "chrome/browser/prerender/prerender_condition.h" | 18 #include "chrome/browser/prerender/prerender_condition.h" |
20 #include "chrome/browser/prerender/prerender_contents.h" | 19 #include "chrome/browser/prerender/prerender_contents.h" |
21 #include "chrome/browser/prerender/prerender_final_status.h" | 20 #include "chrome/browser/prerender/prerender_final_status.h" |
| 21 #include "chrome/browser/prerender/prerender_histograms.h" |
22 #include "chrome/browser/prerender/prerender_history.h" | 22 #include "chrome/browser/prerender/prerender_history.h" |
23 #include "chrome/browser/prerender/prerender_observer.h" | 23 #include "chrome/browser/prerender/prerender_observer.h" |
24 #include "chrome/browser/prerender/prerender_tracker.h" | 24 #include "chrome/browser/prerender/prerender_tracker.h" |
25 #include "chrome/browser/prerender/prerender_util.h" | 25 #include "chrome/browser/prerender/prerender_util.h" |
26 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
28 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" | 28 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" |
29 #include "chrome/common/chrome_switches.h" | 29 #include "chrome/common/chrome_switches.h" |
30 #include "chrome/common/render_messages.h" | 30 #include "chrome/common/render_messages.h" |
31 #include "content/browser/browser_thread.h" | 31 #include "content/browser/browser_thread.h" |
(...skipping 29 matching lines...) Expand all Loading... |
61 "OPTIONS", | 61 "OPTIONS", |
62 "POST", | 62 "POST", |
63 "TRACE", | 63 "TRACE", |
64 }; | 64 }; |
65 | 65 |
66 // Length of prerender history, for display in chrome://net-internals | 66 // Length of prerender history, for display in chrome://net-internals |
67 const int kHistoryLength = 100; | 67 const int kHistoryLength = 100; |
68 | 68 |
69 } // namespace | 69 } // namespace |
70 | 70 |
71 // Helper macros for experiment-based and origin-based histogram reporting. | |
72 #define PREFIXED_HISTOGRAM(histogram) \ | |
73 PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \ | |
74 IsOriginExperimentWash(), histogram) | |
75 | |
76 #define PREFIXED_HISTOGRAM_PRERENDER_MANAGER(pm, histogram) \ | |
77 PREFIXED_HISTOGRAM_INTERNAL(pm->GetCurrentOrigin(), \ | |
78 pm->GetCurrentExperimentId(), \ | |
79 pm->IsOriginExperimentWash(), histogram) | |
80 | |
81 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \ | |
82 PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram) | |
83 | |
84 #define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \ | |
85 static uint8 recording_experiment = kNoExperiment; \ | |
86 if (recording_experiment == kNoExperiment && experiment != kNoExperiment) \ | |
87 recording_experiment = experiment; \ | |
88 if (wash) { \ | |
89 histogram; \ | |
90 } else if (experiment != kNoExperiment && \ | |
91 (origin != ORIGIN_LINK_REL_PRERENDER || \ | |
92 experiment != recording_experiment)) { \ | |
93 } else if (experiment != kNoExperiment) { \ | |
94 histogram; \ | |
95 } else if (origin == ORIGIN_OMNIBOX) { \ | |
96 histogram; \ | |
97 } else { \ | |
98 histogram; \ | |
99 } \ | |
100 } | |
101 | |
102 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { | 71 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { |
103 public: | 72 public: |
104 OnCloseTabContentsDeleter(PrerenderManager* manager, | 73 OnCloseTabContentsDeleter(PrerenderManager* manager, |
105 TabContentsWrapper* tab) | 74 TabContentsWrapper* tab) |
106 : manager_(manager), | 75 : manager_(manager), |
107 tab_(tab) { | 76 tab_(tab) { |
108 tab_->tab_contents()->set_delegate(this); | 77 tab_->tab_contents()->set_delegate(this); |
109 } | 78 } |
110 | 79 |
111 virtual void CloseContents(TabContents* source) OVERRIDE { | 80 virtual void CloseContents(TabContents* source) OVERRIDE { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 GURL referrer_; | 165 GURL referrer_; |
197 Origin origin_; | 166 Origin origin_; |
198 }; | 167 }; |
199 | 168 |
200 PrerenderManager::PrerenderManager(Profile* profile, | 169 PrerenderManager::PrerenderManager(Profile* profile, |
201 PrerenderTracker* prerender_tracker) | 170 PrerenderTracker* prerender_tracker) |
202 : enabled_(true), | 171 : enabled_(true), |
203 profile_(profile), | 172 profile_(profile), |
204 prerender_tracker_(prerender_tracker), | 173 prerender_tracker_(prerender_tracker), |
205 prerender_contents_factory_(PrerenderContents::CreateFactory()), | 174 prerender_contents_factory_(PrerenderContents::CreateFactory()), |
206 last_experiment_id_(kNoExperiment), | |
207 last_origin_(ORIGIN_LINK_REL_PRERENDER), | |
208 origin_experiment_wash_(false), | |
209 last_prerender_start_time_(GetCurrentTimeTicks() - | 175 last_prerender_start_time_(GetCurrentTimeTicks() - |
210 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), | 176 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), |
211 runnable_method_factory_(this), | 177 runnable_method_factory_(this), |
212 prerender_history_(new PrerenderHistory(kHistoryLength)) { | 178 prerender_history_(new PrerenderHistory(kHistoryLength)), |
| 179 histograms_(new PrerenderHistograms()) { |
213 // There are some assumptions that the PrerenderManager is on the UI thread. | 180 // There are some assumptions that the PrerenderManager is on the UI thread. |
214 // Any other checks simply make sure that the PrerenderManager is accessed on | 181 // Any other checks simply make sure that the PrerenderManager is accessed on |
215 // the same thread that it was created on. | 182 // the same thread that it was created on. |
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
217 } | 184 } |
218 | 185 |
219 PrerenderManager::~PrerenderManager() { | 186 PrerenderManager::~PrerenderManager() { |
220 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); | 187 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); |
221 STLDeleteElements(&prerender_conditions_); | 188 STLDeleteElements(&prerender_conditions_); |
222 } | 189 } |
(...skipping 23 matching lines...) Expand all Loading... |
246 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL()); | 213 return AddPrerender(ORIGIN_OMNIBOX, std::make_pair(-1, -1), url, GURL()); |
247 } | 214 } |
248 | 215 |
249 bool PrerenderManager::AddPrerender( | 216 bool PrerenderManager::AddPrerender( |
250 Origin origin, | 217 Origin origin, |
251 const std::pair<int, int>& child_route_id_pair, | 218 const std::pair<int, int>& child_route_id_pair, |
252 const GURL& url_arg, | 219 const GURL& url_arg, |
253 const GURL& referrer) { | 220 const GURL& referrer) { |
254 DCHECK(CalledOnValidThread()); | 221 DCHECK(CalledOnValidThread()); |
255 | 222 |
256 // Check if we are doing an experiment. | 223 if (origin == ORIGIN_LINK_REL_PRERENDER && |
257 uint8 experiment = GetQueryStringBasedExperiment(url_arg); | 224 StartsWithASCII(referrer.host(), std::string("www.google."), true)) { |
258 | 225 origin = ORIGIN_GWS_PRERENDER; |
259 // We need to update last_experiment_id_, last_origin_, and | |
260 // origin_experiment_wash_. | |
261 if (!WithinWindow()) { | |
262 // If we are outside a window, this is a fresh start and we are fine, | |
263 // and there is no mix. | |
264 origin_experiment_wash_ = false; | |
265 } else { | |
266 // If we are inside the last window, there is a mish mash of origins | |
267 // and experiments if either there was a mish mash before, or the current | |
268 // experiment/origin does not match the previous one. | |
269 if (experiment != last_experiment_id_ || origin != last_origin_) | |
270 origin_experiment_wash_ = true; | |
271 } | 226 } |
272 | 227 |
273 last_origin_ = origin; | 228 histograms_->RecordPrerender(origin, url_arg); |
274 last_experiment_id_ = experiment; | |
275 | |
276 // If we observe multiple tags within the 30 second window, we will still | |
277 // reset the window to begin at the most recent occurrence, so that we will | |
278 // always be in a window in the 30 seconds from each occurrence. | |
279 last_prerender_seen_time_ = GetCurrentTimeTicks(); | |
280 | 229 |
281 // If the referring page is prerendering, defer the prerender. | 230 // If the referring page is prerendering, defer the prerender. |
282 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != | 231 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != |
283 prerender_list_.end()) { | 232 prerender_list_.end()) { |
284 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer); | 233 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer); |
285 return true; | 234 return true; |
286 } | 235 } |
287 | 236 |
288 DeleteOldEntries(); | 237 DeleteOldEntries(); |
289 DeletePendingDeleteEntries(); | 238 DeletePendingDeleteEntries(); |
290 | 239 |
291 GURL url = url_arg; | 240 GURL url = url_arg; |
292 GURL alias_url; | 241 GURL alias_url; |
293 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) { | 242 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) { |
294 url = alias_url; | 243 url = alias_url; |
295 } | 244 } |
296 | 245 |
297 if (FindEntry(url)) | 246 if (FindEntry(url)) |
298 return false; | 247 return false; |
299 | 248 |
| 249 uint8 experiment = GetQueryStringBasedExperiment(url_arg); |
| 250 |
300 // Do not prerender if there are too many render processes, and we would | 251 // Do not prerender if there are too many render processes, and we would |
301 // have to use an existing one. We do not want prerendering to happen in | 252 // have to use an existing one. We do not want prerendering to happen in |
302 // a shared process, so that we can always reliably lower the CPU | 253 // a shared process, so that we can always reliably lower the CPU |
303 // priority for prerendering. | 254 // priority for prerendering. |
304 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns | 255 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns |
305 // true, so that case needs to be explicitly checked for. | 256 // true, so that case needs to be explicitly checked for. |
306 // TODO(tburkard): Figure out how to cancel prerendering in the opposite | 257 // TODO(tburkard): Figure out how to cancel prerendering in the opposite |
307 // case, when a new tab is added to a process used for prerendering. | 258 // case, when a new tab is added to a process used for prerendering. |
308 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && | 259 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && |
309 !RenderProcessHost::run_renderer_in_process()) { | 260 !RenderProcessHost::run_renderer_in_process()) { |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 int child_id, route_id; | 455 int child_id, route_id; |
505 CHECK(prerender_contents->GetChildId(&child_id)); | 456 CHECK(prerender_contents->GetChildId(&child_id)); |
506 CHECK(prerender_contents->GetRouteId(&route_id)); | 457 CHECK(prerender_contents->GetRouteId(&route_id)); |
507 | 458 |
508 // Try to set the prerendered page as used, so any subsequent attempts to | 459 // Try to set the prerendered page as used, so any subsequent attempts to |
509 // cancel on other threads will fail. If this fails because the prerender | 460 // cancel on other threads will fail. If this fails because the prerender |
510 // was already cancelled, possibly on another thread, fail. | 461 // was already cancelled, possibly on another thread, fail. |
511 if (!prerender_tracker_->TryUse(child_id, route_id)) | 462 if (!prerender_tracker_->TryUse(child_id, route_id)) |
512 return false; | 463 return false; |
513 | 464 |
514 if (!prerender_contents->load_start_time().is_null()) | 465 if (!prerender_contents->load_start_time().is_null()) { |
515 RecordTimeUntilUsed(GetCurrentTimeTicks() - | 466 histograms_->RecordTimeUntilUsed(GetCurrentTimeTicks() - |
516 prerender_contents->load_start_time()); | 467 prerender_contents->load_start_time(), |
| 468 config_.max_age); |
| 469 } |
517 | 470 |
518 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS( | 471 histograms_->RecordPerSessionCount(++prerenders_per_session_count_); |
519 GetDefaultHistogramName("PrerendersPerSessionCount"), | |
520 ++prerenders_per_session_count_)); | |
521 prerender_contents->set_final_status(FINAL_STATUS_USED); | 472 prerender_contents->set_final_status(FINAL_STATUS_USED); |
522 | 473 |
523 RenderViewHost* render_view_host = | 474 RenderViewHost* render_view_host = |
524 prerender_contents->prerender_contents()->render_view_host(); | 475 prerender_contents->prerender_contents()->render_view_host(); |
525 DCHECK(render_view_host); | 476 DCHECK(render_view_host); |
526 render_view_host->Send( | 477 render_view_host->Send( |
527 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); | 478 new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false)); |
528 | 479 |
529 TabContentsWrapper* new_tab_contents = | 480 TabContentsWrapper* new_tab_contents = |
530 prerender_contents->ReleasePrerenderContents(); | 481 prerender_contents->ReleasePrerenderContents(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 } | 600 } |
650 | 601 |
651 void PrerenderManager::DeletePendingDeleteEntries() { | 602 void PrerenderManager::DeletePendingDeleteEntries() { |
652 while (!pending_delete_list_.empty()) { | 603 while (!pending_delete_list_.empty()) { |
653 PrerenderContents* contents = pending_delete_list_.front(); | 604 PrerenderContents* contents = pending_delete_list_.front(); |
654 pending_delete_list_.pop_front(); | 605 pending_delete_list_.pop_front(); |
655 delete contents; | 606 delete contents; |
656 } | 607 } |
657 } | 608 } |
658 | 609 |
659 // Helper macro for histograms. | |
660 #define RECORD_PLT(tag, perceived_page_load_time) { \ | |
661 PREFIXED_HISTOGRAM_PRERENDER_MANAGER(prerender_manager, \ | |
662 UMA_HISTOGRAM_CUSTOM_TIMES( \ | |
663 base::FieldTrial::MakeName( \ | |
664 prerender_manager->GetDefaultHistogramName(tag), "Prefetch"), \ | |
665 perceived_page_load_time, \ | |
666 base::TimeDelta::FromMilliseconds(10), \ | |
667 base::TimeDelta::FromSeconds(60), \ | |
668 100)); \ | |
669 } | |
670 | |
671 // static | 610 // static |
672 void PrerenderManager::RecordPerceivedPageLoadTime( | 611 void PrerenderManager::RecordPerceivedPageLoadTime( |
673 base::TimeDelta perceived_page_load_time, | 612 base::TimeDelta perceived_page_load_time, |
674 TabContents* tab_contents) { | 613 TabContents* tab_contents) { |
675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 614 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
676 Profile* profile = | 615 Profile* profile = |
677 Profile::FromBrowserContext(tab_contents->browser_context()); | 616 Profile::FromBrowserContext(tab_contents->browser_context()); |
678 PrerenderManager* prerender_manager = profile->GetPrerenderManager(); | 617 PrerenderManager* prerender_manager = profile->GetPrerenderManager(); |
679 if (!prerender_manager) | 618 if (!prerender_manager) |
680 return; | 619 return; |
681 if (!prerender_manager->is_enabled()) | 620 if (!prerender_manager->is_enabled()) |
682 return; | 621 return; |
683 bool within_window = prerender_manager->WithinWindow(); | 622 bool was_prerender = |
684 RECORD_PLT("PerceivedPLT", perceived_page_load_time); | |
685 if (within_window) | |
686 RECORD_PLT("PerceivedPLTWindowed", perceived_page_load_time); | |
687 if (prerender_manager && | |
688 ((mode_ == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP && | 623 ((mode_ == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP && |
689 prerender_manager->WouldTabContentsBePrerendered(tab_contents)) || | 624 prerender_manager->WouldTabContentsBePrerendered(tab_contents)) || |
690 (mode_ == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP && | 625 (mode_ == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP && |
691 prerender_manager->IsTabContentsPrerendered(tab_contents)))) { | 626 prerender_manager->IsTabContentsPrerendered(tab_contents))); |
692 RECORD_PLT("PerceivedPLTMatched", perceived_page_load_time); | 627 prerender_manager->histograms_->RecordPerceivedPageLoadTime( |
693 } else { | 628 perceived_page_load_time, was_prerender); |
694 if (within_window) | |
695 RECORD_PLT("PerceivedPLTWindowNotMatched", perceived_page_load_time); | |
696 } | |
697 } | 629 } |
698 | 630 |
699 bool PrerenderManager::is_enabled() const { | 631 bool PrerenderManager::is_enabled() const { |
700 DCHECK(CalledOnValidThread()); | 632 DCHECK(CalledOnValidThread()); |
701 if (!enabled_) | 633 if (!enabled_) |
702 return false; | 634 return false; |
703 for (std::list<const PrerenderCondition*>::const_iterator it = | 635 for (std::list<const PrerenderCondition*>::const_iterator it = |
704 prerender_conditions_.begin(); | 636 prerender_conditions_.begin(); |
705 it != prerender_conditions_.end(); | 637 it != prerender_conditions_.end(); |
706 ++it) { | 638 ++it) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); | 691 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); |
760 | 692 |
761 // If the entry doesn't have a RenderViewHost then it didn't start | 693 // If the entry doesn't have a RenderViewHost then it didn't start |
762 // prerendering and there shouldn't be any pending preloads to remove. | 694 // prerendering and there shouldn't be any pending preloads to remove. |
763 if (has_child_id && has_route_id) { | 695 if (has_child_id && has_route_id) { |
764 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); | 696 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); |
765 pending_prerender_list_.erase(child_route_pair); | 697 pending_prerender_list_.erase(child_route_pair); |
766 } | 698 } |
767 } | 699 } |
768 | 700 |
769 bool PrerenderManager::WithinWindow() const { | |
770 DCHECK(CalledOnValidThread()); | |
771 if (last_prerender_seen_time_.is_null()) | |
772 return false; | |
773 base::TimeDelta elapsed_time = | |
774 base::TimeTicks::Now() - last_prerender_seen_time_; | |
775 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds); | |
776 } | |
777 | |
778 bool PrerenderManager::DoesRateLimitAllowPrerender() const { | 701 bool PrerenderManager::DoesRateLimitAllowPrerender() const { |
779 DCHECK(CalledOnValidThread()); | 702 DCHECK(CalledOnValidThread()); |
780 base::TimeDelta elapsed_time = | 703 base::TimeDelta elapsed_time = |
781 GetCurrentTimeTicks() - last_prerender_start_time_; | 704 GetCurrentTimeTicks() - last_prerender_start_time_; |
782 PREFIXED_HISTOGRAM( | 705 histograms_->RecordTimeBetweenPrerenderRequests(elapsed_time); |
783 UMA_HISTOGRAM_TIMES( | |
784 GetDefaultHistogramName("TimeBetweenPrerenderRequests"), | |
785 elapsed_time)); | |
786 if (!config_.rate_limit_enabled) | 706 if (!config_.rate_limit_enabled) |
787 return true; | 707 return true; |
788 return elapsed_time > | 708 return elapsed_time > |
789 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); | 709 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); |
790 } | 710 } |
791 | 711 |
792 void PrerenderManager::StartSchedulingPeriodicCleanups() { | 712 void PrerenderManager::StartSchedulingPeriodicCleanups() { |
793 DCHECK(CalledOnValidThread()); | 713 DCHECK(CalledOnValidThread()); |
794 if (repeating_timer_.IsRunning()) | 714 if (repeating_timer_.IsRunning()) |
795 return; | 715 return; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { | 934 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { |
1015 DeleteOldTabContents(); | 935 DeleteOldTabContents(); |
1016 while (!prerender_list_.empty()) { | 936 while (!prerender_list_.empty()) { |
1017 PrerenderContentsData data = prerender_list_.front(); | 937 PrerenderContentsData data = prerender_list_.front(); |
1018 prerender_list_.pop_front(); | 938 prerender_list_.pop_front(); |
1019 data.contents_->Destroy(final_status); | 939 data.contents_->Destroy(final_status); |
1020 } | 940 } |
1021 DeletePendingDeleteEntries(); | 941 DeletePendingDeleteEntries(); |
1022 } | 942 } |
1023 | 943 |
1024 void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) { | |
1025 DCHECK(CalledOnValidThread()); | |
1026 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES( | |
1027 GetDefaultHistogramName("TimeUntilUsed"), | |
1028 time_until_used, | |
1029 base::TimeDelta::FromMilliseconds(10), | |
1030 config_.max_age, | |
1031 50)); | |
1032 } | |
1033 | |
1034 void PrerenderManager::RecordFinalStatus(Origin origin, | 944 void PrerenderManager::RecordFinalStatus(Origin origin, |
1035 uint8 experiment_id, | 945 uint8 experiment_id, |
1036 FinalStatus final_status) const { | 946 FinalStatus final_status) const { |
1037 DCHECK(final_status != FINAL_STATUS_MAX); | 947 histograms_->RecordFinalStatus(origin, experiment_id, final_status); |
1038 // FINAL_STATUS_CONTROL_GROUP indicates that the PrerenderContents | |
1039 // was created only to measure "would-have-been-prerendered" for | |
1040 // control group measurements. Don't pollute data with it. | |
1041 if (PrerenderManager::IsControlGroup() || | |
1042 final_status == FINAL_STATUS_CONTROL_GROUP) | |
1043 return; | |
1044 PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id, | |
1045 UMA_HISTOGRAM_ENUMERATION( | |
1046 GetHistogramName(origin, experiment_id, "FinalStatus"), | |
1047 final_status, | |
1048 FINAL_STATUS_MAX)); | |
1049 } | |
1050 | |
1051 std::string PrerenderManager::ComposeHistogramName( | |
1052 const std::string& prefix_type, | |
1053 const std::string& name) const { | |
1054 if (prefix_type.empty()) | |
1055 return std::string("Prerender.") + name; | |
1056 return std::string("Prerender.") + prefix_type + std::string("_") + name; | |
1057 } | |
1058 | |
1059 std::string PrerenderManager::GetHistogramName(Origin origin, | |
1060 uint8 experiment_id, | |
1061 const std::string& name) const { | |
1062 switch (origin) { | |
1063 case ORIGIN_OMNIBOX: | |
1064 if (experiment_id != kNoExperiment) | |
1065 return ComposeHistogramName("wash", name); | |
1066 return ComposeHistogramName("omnibox", name); | |
1067 case ORIGIN_LINK_REL_PRERENDER: | |
1068 if (experiment_id == kNoExperiment) | |
1069 return ComposeHistogramName("", name); | |
1070 return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'), | |
1071 name); | |
1072 default: | |
1073 NOTREACHED(); | |
1074 break; | |
1075 }; | |
1076 | |
1077 // Dummy return value to make the compiler happy. | |
1078 NOTREACHED(); | |
1079 return ComposeHistogramName("wash", name); | |
1080 } | |
1081 | |
1082 std::string PrerenderManager::GetDefaultHistogramName( | |
1083 const std::string& name) const { | |
1084 if (!WithinWindow()) | |
1085 return ComposeHistogramName("", name); | |
1086 if (origin_experiment_wash_) | |
1087 return ComposeHistogramName("wash", name); | |
1088 return GetHistogramName(last_origin_, last_experiment_id_, name); | |
1089 } | |
1090 | |
1091 uint8 PrerenderManager::GetCurrentExperimentId() const { | |
1092 if (!WithinWindow()) | |
1093 return kNoExperiment; | |
1094 return last_experiment_id_; | |
1095 } | |
1096 | |
1097 Origin PrerenderManager::GetCurrentOrigin() const { | |
1098 if (!WithinWindow()) | |
1099 return ORIGIN_LINK_REL_PRERENDER; | |
1100 return last_origin_; | |
1101 } | |
1102 | |
1103 bool PrerenderManager::IsOriginExperimentWash() const { | |
1104 if (!WithinWindow()) | |
1105 return false; | |
1106 return origin_experiment_wash_; | |
1107 } | 948 } |
1108 | 949 |
1109 } // namespace prerender | 950 } // namespace prerender |
OLD | NEW |