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

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

Issue 9270018: Make a separate histogram for MatchComplete Final Status'es and (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 "POST", 77 "POST",
78 "TRACE", 78 "TRACE",
79 }; 79 };
80 80
81 // Length of prerender history, for display in chrome://net-internals 81 // Length of prerender history, for display in chrome://net-internals
82 const int kHistoryLength = 100; 82 const int kHistoryLength = 100;
83 83
84 // Indicates whether a Prerender has been cancelled such that we need 84 // Indicates whether a Prerender has been cancelled such that we need
85 // a dummy replacement for the purpose of recording the correct PPLT for 85 // a dummy replacement for the purpose of recording the correct PPLT for
86 // the Match Complete case. 86 // the Match Complete case.
87 // Traditionally, "Match" means that a prerendered page was actually visited &
dominich 2012/01/20 22:23:37 Match? or MatchComplete?
tburkard 2012/01/20 23:23:00 What I wrote is correct, I think. On 2012/01/20 22
88 // the prerender was used. Our goal is to have "Match" cases line up in the
89 // control group & the experiment group, so that we can make meaningful
90 // comparisons of improvements. However, in the control group, since we don't
91 // actually perform prerenders, many of the cancellation reasons cannot be
92 // detected. Therefore, in the Prerender group, when we cancel for one of these
93 // reasons, we keep track of a dummy Prerender representing what we would
94 // have in the control group. If that dummy prerender in the prerender group
95 // would then be swapped in (but isn't actually b/c it's a dummy), we record
96 // this as a MatchComplete. This allows us to compare MatchComplete's
97 // across Prerender & Control group which ideally should be lining up.
98 // This ensures that, by comparing a larger Match in Control vs. a smaller Match
dominich 2012/01/20 22:23:37 Match or MatchComplete?
tburkard 2012/01/20 23:23:00 Done.
99 // in the Prerender group, there is no bias in terms of the page load times
100 // of the pages forming the difference between the two sets.
87 101
88 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) { 102 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) {
89 return final_status != FINAL_STATUS_USED && 103 return final_status != FINAL_STATUS_USED &&
dominich 2012/01/20 22:23:37 Might this be easier as an inclusive check rather
tburkard 2012/01/20 23:23:00 No, because as new status'es are added, the defaul
90 final_status != FINAL_STATUS_TIMED_OUT && 104 final_status != FINAL_STATUS_TIMED_OUT &&
91 final_status != FINAL_STATUS_EVICTED && 105 final_status != FINAL_STATUS_EVICTED &&
92 final_status != FINAL_STATUS_MANAGER_SHUTDOWN && 106 final_status != FINAL_STATUS_MANAGER_SHUTDOWN &&
93 final_status != FINAL_STATUS_APP_TERMINATING && 107 final_status != FINAL_STATUS_APP_TERMINATING &&
94 final_status != FINAL_STATUS_RENDERER_CRASHED && 108 final_status != FINAL_STATUS_RENDERER_CRASHED &&
95 final_status != FINAL_STATUS_WINDOW_OPENER && 109 final_status != FINAL_STATUS_WINDOW_OPENER &&
96 final_status != FINAL_STATUS_FRAGMENT_MISMATCH && 110 final_status != FINAL_STATUS_FRAGMENT_MISMATCH &&
97 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && 111 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED &&
98 final_status != FINAL_STATUS_CANCELLED && 112 final_status != FINAL_STATUS_CANCELLED &&
113 final_status != FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH &&
114 final_status != FINAL_STATUS_DEVTOOLS_ATTACHED &&
115 final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING &&
99 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; 116 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY;
100 } 117 }
101 118
102 } // namespace 119 } // namespace
103 120
104 class PrerenderManager::OnCloseTabContentsDeleter 121 class PrerenderManager::OnCloseTabContentsDeleter
105 : public content::WebContentsDelegate, 122 : public content::WebContentsDelegate,
106 public base::SupportsWeakPtr< 123 public base::SupportsWeakPtr<
107 PrerenderManager::OnCloseTabContentsDeleter> { 124 PrerenderManager::OnCloseTabContentsDeleter> {
108 public: 125 public:
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!prerender_contents || !prerender_contents->Init()) 447 if (!prerender_contents || !prerender_contents->Init())
431 return false; 448 return false;
432 449
433 histograms_->RecordPrerenderStarted(origin); 450 histograms_->RecordPrerenderStarted(origin);
434 451
435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 452 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 453 PrerenderContentsData data(prerender_contents, GetCurrentTime());
437 454
438 prerender_list_.push_back(data); 455 prerender_list_.push_back(data);
439 456
440 if (IsControlGroup()) { 457 if (!IsControlGroup()) {
441 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
442 } else {
443 last_prerender_start_time_ = GetCurrentTimeTicks(); 458 last_prerender_start_time_ = GetCurrentTimeTicks();
444 data.contents_->StartPrerendering(source_render_view_host, 459 data.contents_->StartPrerendering(source_render_view_host,
445 session_storage_namespace); 460 session_storage_namespace);
446 } 461 }
447 while (prerender_list_.size() > config_.max_elements) { 462 while (prerender_list_.size() > config_.max_elements) {
448 data = prerender_list_.front(); 463 data = prerender_list_.front();
449 prerender_list_.pop_front(); 464 prerender_list_.pop_front();
450 data.contents_->Destroy(FINAL_STATUS_EVICTED); 465 data.contents_->Destroy(FINAL_STATUS_EVICTED);
451 } 466 }
452 StartSchedulingPeriodicCleanups(); 467 StartSchedulingPeriodicCleanups();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 542 }
528 } 543 }
529 // Entry not found. 544 // Entry not found.
530 return NULL; 545 return NULL;
531 } 546 }
532 547
533 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { 548 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) {
534 return GetEntryButNotSpecifiedWC(url, NULL); 549 return GetEntryButNotSpecifiedWC(url, NULL);
535 } 550 }
536 551
552 void PrerenderManager::DestroyAndMarkMatchCompleteAsUsed(
553 PrerenderContents* prerender_contents,
554 FinalStatus final_status) {
555 prerender_contents->set_mc_status(PrerenderContents::MC_REPLACED);
556 histograms_->RecordMatchCompleteFinalStatus(
557 prerender_contents->origin(),
558 prerender_contents->experiment_id(),
559 FINAL_STATUS_USED);
560 prerender_contents->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED);
dominich 2012/01/20 22:23:37 This should be |final_status|. You might need a te
tburkard 2012/01/20 23:23:00 Great catch. Haven't even run/written tests yet w
561 }
562
537 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, 563 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
538 const GURL& url, 564 const GURL& url,
539 const GURL& opener_url) { 565 const GURL& opener_url) {
540 DCHECK(CalledOnValidThread()); 566 DCHECK(CalledOnValidThread());
541 RecordNavigation(url); 567 RecordNavigation(url);
542 568
543 scoped_ptr<PrerenderContents> prerender_contents( 569 scoped_ptr<PrerenderContents> prerender_contents(
544 GetEntryButNotSpecifiedWC(url, web_contents)); 570 GetEntryButNotSpecifiedWC(url, web_contents));
545 if (prerender_contents.get() == NULL) 571 if (prerender_contents.get() == NULL)
546 return false; 572 return false;
(...skipping 13 matching lines...) Expand all
560 bool url_matches = prerender_contents->MatchesURL(url, &matching_url); 586 bool url_matches = prerender_contents->MatchesURL(url, &matching_url);
561 DCHECK(url_matches); 587 DCHECK(url_matches);
562 if (url_matches && url.ref() != matching_url.ref()) { 588 if (url_matches && url.ref() != matching_url.ref()) {
563 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH); 589 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH);
564 return false; 590 return false;
565 } 591 }
566 592
567 // If we are just in the control group (which can be detected by noticing 593 // If we are just in the control group (which can be detected by noticing
568 // that prerendering hasn't even started yet), record that |web_contents| now 594 // that prerendering hasn't even started yet), record that |web_contents| now
569 // would be showing a prerendered contents, but otherwise, don't do anything. 595 // would be showing a prerendered contents, but otherwise, don't do anything.
570 if (!prerender_contents->prerendering_has_started()) { 596 if (!prerender_contents->prerendering_has_started()) {
dominich 2012/01/20 22:23:37 Why is this different to IsControlGroup?
tburkard 2012/01/20 23:23:00 I already answered this before, I said: This is ne
571 MarkWebContentsAsWouldBePrerendered(web_contents); 597 MarkWebContentsAsWouldBePrerendered(web_contents);
598 prerender_contents.release()->Destroy(FINAL_STATUS_USED);
572 return false; 599 return false;
573 } 600 }
574 601
575 // Don't use prerendered pages if debugger is attached to the tab. 602 // Don't use prerendered pages if debugger is attached to the tab.
576 // See http://crbug.com/98541 603 // See http://crbug.com/98541
577 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { 604 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) {
578 prerender_contents.release()->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED); 605 DestroyAndMarkMatchCompleteAsUsed(prerender_contents.release(),
606 FINAL_STATUS_DEVTOOLS_ATTACHED);
579 return false; 607 return false;
580 } 608 }
581 609
582 // If the prerendered page is in the middle of a cross-site navigation, 610 // If the prerendered page is in the middle of a cross-site navigation,
583 // don't swap it in because there isn't a good way to merge histories. 611 // don't swap it in because there isn't a good way to merge histories.
584 if (prerender_contents->IsCrossSiteNavigationPending()) { 612 if (prerender_contents->IsCrossSiteNavigationPending()) {
585 prerender_contents.release()->Destroy( 613 DestroyAndMarkMatchCompleteAsUsed(
614 prerender_contents.release(),
586 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); 615 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
587 return false; 616 return false;
588 } 617 }
589 618
590 // If the session storage namespaces don't match, cancel the prerender. 619 // If the session storage namespaces don't match, cancel the prerender.
591 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost(); 620 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost();
592 RenderViewHost* new_render_view_host = 621 RenderViewHost* new_render_view_host =
593 prerender_contents->prerender_contents()->web_contents()-> 622 prerender_contents->prerender_contents()->web_contents()->
594 GetRenderViewHost(); 623 GetRenderViewHost();
595 DCHECK(old_render_view_host); 624 DCHECK(old_render_view_host);
596 DCHECK(new_render_view_host); 625 DCHECK(new_render_view_host);
597 if (old_render_view_host->session_storage_namespace() != 626 if (old_render_view_host->session_storage_namespace() !=
598 new_render_view_host->session_storage_namespace()) { 627 new_render_view_host->session_storage_namespace()) {
599 prerender_contents.release()->Destroy( 628 DestroyAndMarkMatchCompleteAsUsed(
629 prerender_contents.release(),
600 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH); 630 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH);
601 return false; 631 return false;
602 } 632 }
603 633
604 // If we don't want to use prerenders at all, we are done. 634 // If we don't want to use prerenders at all, we are done.
605 // For bookkeeping purposes, we need to mark this TabContents to 635 // For bookkeeping purposes, we need to mark this TabContents to
606 // reflect that it would have been prerendered. 636 // reflect that it would have been prerendered.
607 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { 637 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
608 MarkWebContentsAsWouldBePrerendered(web_contents); 638 MarkWebContentsAsWouldBePrerendered(web_contents);
609 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP); 639 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 it != prerender_list_.end(); 728 it != prerender_list_.end();
699 ++it) { 729 ++it) {
700 if (it->contents_ == entry) { 730 if (it->contents_ == entry) {
701 bool swapped_in_dummy_replacement = false; 731 bool swapped_in_dummy_replacement = false;
702 732
703 // If this PrerenderContents is being deleted due to a cancellation, 733 // If this PrerenderContents is being deleted due to a cancellation,
704 // we need to create a dummy replacement for PPLT accounting purposes 734 // we need to create a dummy replacement for PPLT accounting purposes
705 // for the Match Complete group. 735 // for the Match Complete group.
706 // This is the case if the cancellation is for any reason that would not 736 // This is the case if the cancellation is for any reason that would not
707 // occur in the control group case. 737 // occur in the control group case.
708 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { 738 if (entry->mc_status() == PrerenderContents::MC_DEFAULT &&
dominich 2012/01/20 22:23:37 if mc_status is only set from this method, this co
tburkard 2012/01/20 23:23:00 huh? why? Can you give an example? A prerender
739 NeedMatchCompleteDummyForFinalStatus(final_status)) {
709 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. 740 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering.
710 // However, what if new conditions are added and 741 // However, what if new conditions are added and
711 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure 742 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure
712 // what's the best thing to do here. For now, I will just check whether 743 // what's the best thing to do here. For now, I will just check whether
713 // we are actually prerendering. 744 // we are actually prerendering.
714 if (ActuallyPrerendering()) { 745 if (ActuallyPrerendering()) {
746 entry->set_mc_status(PrerenderContents::MC_REPLACED);
715 PrerenderContents* dummy_replacement_prerender_contents = 747 PrerenderContents* dummy_replacement_prerender_contents =
716 CreatePrerenderContents( 748 CreatePrerenderContents(
717 entry->prerender_url(), 749 entry->prerender_url(),
718 entry->referrer(), 750 entry->referrer(),
719 entry->origin(), 751 entry->origin(),
720 entry->experiment_id()); 752 entry->experiment_id());
721 if (dummy_replacement_prerender_contents && 753 if (dummy_replacement_prerender_contents &&
722 dummy_replacement_prerender_contents->Init()) { 754 dummy_replacement_prerender_contents->Init()) {
723 dummy_replacement_prerender_contents-> 755 dummy_replacement_prerender_contents->
724 AddAliasURLsFromOtherPrerenderContents(entry); 756 AddAliasURLsFromOtherPrerenderContents(entry);
757 dummy_replacement_prerender_contents->set_mc_status(
758 PrerenderContents::MC_REPLACEMENT);
725 it->contents_ = dummy_replacement_prerender_contents; 759 it->contents_ = dummy_replacement_prerender_contents;
726 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY);
727 swapped_in_dummy_replacement = true; 760 swapped_in_dummy_replacement = true;
728 } 761 }
729 } 762 }
730 } 763 }
731 if (!swapped_in_dummy_replacement) 764 if (!swapped_in_dummy_replacement)
732 prerender_list_.erase(it); 765 prerender_list_.erase(it);
733 break; 766 break;
734 } 767 }
735 } 768 }
736 AddToHistory(entry); 769 AddToHistory(entry);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { 1125 void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
1093 DeleteOldTabContents(); 1126 DeleteOldTabContents();
1094 while (!prerender_list_.empty()) { 1127 while (!prerender_list_.empty()) {
1095 PrerenderContentsData data = prerender_list_.front(); 1128 PrerenderContentsData data = prerender_list_.front();
1096 prerender_list_.pop_front(); 1129 prerender_list_.pop_front();
1097 data.contents_->Destroy(final_status); 1130 data.contents_->Destroy(final_status);
1098 } 1131 }
1099 DeletePendingDeleteEntries(); 1132 DeletePendingDeleteEntries();
1100 } 1133 }
1101 1134
1135 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus(
1136 Origin origin,
1137 uint8 experiment_id,
1138 PrerenderContents::MatchCompleteStatus mc_status,
1139 FinalStatus final_status) const {
dominich 2012/01/20 22:23:37 MC_DEFAULT will be in both histograms. Is this exp
tburkard 2012/01/20 23:23:00 not sure why stuff keeps being repeated. i said e
1140 if (mc_status != PrerenderContents::MC_REPLACEMENT)
1141 histograms_->RecordFinalStatus(origin, experiment_id, final_status);
1142 if (mc_status != PrerenderContents::MC_REPLACED) {
1143 histograms_->RecordMatchCompleteFinalStatus(origin, experiment_id,
1144 final_status);
1145 }
1146 }
1147
1102 void PrerenderManager::RecordFinalStatus(Origin origin, 1148 void PrerenderManager::RecordFinalStatus(Origin origin,
1103 uint8 experiment_id, 1149 uint8 experiment_id,
1104 FinalStatus final_status) const { 1150 FinalStatus final_status) const {
1105 histograms_->RecordFinalStatus(origin, experiment_id, final_status); 1151 RecordFinalStatusWithMatchCompleteStatus(origin, experiment_id,
1152 PrerenderContents::MC_DEFAULT,
1153 final_status);
1106 } 1154 }
1107 1155
1156
1108 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( 1157 PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
1109 int render_process_id) { 1158 int render_process_id) {
1110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1111 content::RenderProcessHost* render_process_host = 1160 content::RenderProcessHost* render_process_host =
1112 content::RenderProcessHost::FromID(render_process_id); 1161 content::RenderProcessHost::FromID(render_process_id);
1113 // Each render process is guaranteed to only hold RenderViews owned by the 1162 // Each render process is guaranteed to only hold RenderViews owned by the
1114 // same BrowserContext. This is enforced by 1163 // same BrowserContext. This is enforced by
1115 // RenderProcessHost::GetExistingProcessHost. 1164 // RenderProcessHost::GetExistingProcessHost.
1116 if (!render_process_host || !render_process_host->GetBrowserContext()) 1165 if (!render_process_host || !render_process_host->GetBrowserContext())
1117 return NULL; 1166 return NULL;
1118 Profile* profile = Profile::FromBrowserContext( 1167 Profile* profile = Profile::FromBrowserContext(
1119 render_process_host->GetBrowserContext()); 1168 render_process_host->GetBrowserContext());
1120 if (!profile) 1169 if (!profile)
1121 return NULL; 1170 return NULL;
1122 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1171 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1123 } 1172 }
1124 1173
1125 } // namespace prerender 1174 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698