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

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 &
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 there is no bias in terms of the page load times
99 // of the pages forming the difference between the two sets.
87 100
88 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) { 101 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) {
cbentzel 2012/01/24 14:55:46 This could return an enum which has three values
cbentzel 2012/01/24 14:55:46 <random thought> I wonder if we should add a table
tburkard 2012/01/24 19:15:54 Ok will think about this for a new CL. On 2012/01/
tburkard 2012/01/24 19:15:54 Yes and no. Here is why I am hesitant to add some
89 return final_status != FINAL_STATUS_USED && 102 return final_status != FINAL_STATUS_USED &&
90 final_status != FINAL_STATUS_TIMED_OUT && 103 final_status != FINAL_STATUS_TIMED_OUT &&
91 final_status != FINAL_STATUS_EVICTED && 104 final_status != FINAL_STATUS_EVICTED &&
92 final_status != FINAL_STATUS_MANAGER_SHUTDOWN && 105 final_status != FINAL_STATUS_MANAGER_SHUTDOWN &&
93 final_status != FINAL_STATUS_APP_TERMINATING && 106 final_status != FINAL_STATUS_APP_TERMINATING &&
94 final_status != FINAL_STATUS_RENDERER_CRASHED && 107 final_status != FINAL_STATUS_RENDERER_CRASHED &&
95 final_status != FINAL_STATUS_WINDOW_OPENER && 108 final_status != FINAL_STATUS_WINDOW_OPENER &&
96 final_status != FINAL_STATUS_FRAGMENT_MISMATCH && 109 final_status != FINAL_STATUS_FRAGMENT_MISMATCH &&
97 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && 110 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED &&
98 final_status != FINAL_STATUS_CANCELLED && 111 final_status != FINAL_STATUS_CANCELLED &&
112 final_status != FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH &&
113 final_status != FINAL_STATUS_DEVTOOLS_ATTACHED &&
114 final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING &&
99 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; 115 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY;
100 } 116 }
101 117
102 } // namespace 118 } // namespace
103 119
104 class PrerenderManager::OnCloseTabContentsDeleter 120 class PrerenderManager::OnCloseTabContentsDeleter
105 : public content::WebContentsDelegate, 121 : public content::WebContentsDelegate,
106 public base::SupportsWeakPtr< 122 public base::SupportsWeakPtr<
107 PrerenderManager::OnCloseTabContentsDeleter> { 123 PrerenderManager::OnCloseTabContentsDeleter> {
108 public: 124 public:
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!prerender_contents || !prerender_contents->Init()) 446 if (!prerender_contents || !prerender_contents->Init())
431 return false; 447 return false;
432 448
433 histograms_->RecordPrerenderStarted(origin); 449 histograms_->RecordPrerenderStarted(origin);
434 450
435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 451 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 452 PrerenderContentsData data(prerender_contents, GetCurrentTime());
437 453
438 prerender_list_.push_back(data); 454 prerender_list_.push_back(data);
439 455
440 if (IsControlGroup()) { 456 if (!IsControlGroup()) {
441 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
cbentzel 2012/01/24 14:55:46 You should add an OBSOLETE comment for FINAL_STATU
tburkard 2012/01/24 19:15:54 Done.
442 } else {
443 last_prerender_start_time_ = GetCurrentTimeTicks(); 457 last_prerender_start_time_ = GetCurrentTimeTicks();
444 data.contents_->StartPrerendering(source_render_view_host, 458 data.contents_->StartPrerendering(source_render_view_host,
445 session_storage_namespace); 459 session_storage_namespace);
446 } 460 }
447 while (prerender_list_.size() > config_.max_elements) { 461 while (prerender_list_.size() > config_.max_elements) {
448 data = prerender_list_.front(); 462 data = prerender_list_.front();
449 prerender_list_.pop_front(); 463 prerender_list_.pop_front();
450 data.contents_->Destroy(FINAL_STATUS_EVICTED); 464 data.contents_->Destroy(FINAL_STATUS_EVICTED);
451 } 465 }
452 StartSchedulingPeriodicCleanups(); 466 StartSchedulingPeriodicCleanups();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 541 }
528 } 542 }
529 // Entry not found. 543 // Entry not found.
530 return NULL; 544 return NULL;
531 } 545 }
532 546
533 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { 547 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) {
534 return GetEntryButNotSpecifiedWC(url, NULL); 548 return GetEntryButNotSpecifiedWC(url, NULL);
535 } 549 }
536 550
551 void PrerenderManager::DestroyAndMarkMatchCompleteAsUsed(
552 PrerenderContents* prerender_contents,
553 FinalStatus final_status) {
554 prerender_contents->set_match_complete_status(
555 PrerenderContents::MATCH_COMPLETE_REPLACED);
556 histograms_->RecordFinalStatus(prerender_contents->origin(),
557 prerender_contents->experiment_id(),
558 PrerenderContents::MATCH_COMPLETE_REPLACEMENT,
559 FINAL_STATUS_USED);
560 prerender_contents->Destroy(final_status);
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 15 matching lines...) Expand all
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()) {
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);
cbentzel 2012/01/24 14:55:46 IMPORTANT: This should just be FINAL_STATUS_USED h
tburkard 2012/01/24 19:15:54 Done.
610 return false; 640 return false;
611 } 641 }
612 642
613 int child_id, route_id; 643 int child_id, route_id;
614 CHECK(prerender_contents->GetChildId(&child_id)); 644 CHECK(prerender_contents->GetChildId(&child_id));
615 CHECK(prerender_contents->GetRouteId(&route_id)); 645 CHECK(prerender_contents->GetRouteId(&route_id));
616 646
617 // Try to set the prerendered page as used, so any subsequent attempts to 647 // Try to set the prerendered page as used, so any subsequent attempts to
618 // cancel on other threads will fail. If this fails because the prerender 648 // cancel on other threads will fail. If this fails because the prerender
619 // was already cancelled, possibly on another thread, fail. 649 // was already cancelled, possibly on another thread, fail.
(...skipping 78 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->match_complete_status() ==
739 PrerenderContents::MATCH_COMPLETE_DEFAULT &&
740 NeedMatchCompleteDummyForFinalStatus(final_status)) {
709 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. 741 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering.
710 // However, what if new conditions are added and 742 // However, what if new conditions are added and
711 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure 743 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure
712 // what's the best thing to do here. For now, I will just check whether 744 // what's the best thing to do here. For now, I will just check whether
713 // we are actually prerendering. 745 // we are actually prerendering.
714 if (ActuallyPrerendering()) { 746 if (ActuallyPrerendering()) {
747 entry->set_match_complete_status(
748 PrerenderContents::MATCH_COMPLETE_REPLACED);
715 PrerenderContents* dummy_replacement_prerender_contents = 749 PrerenderContents* dummy_replacement_prerender_contents =
716 CreatePrerenderContents( 750 CreatePrerenderContents(
717 entry->prerender_url(), 751 entry->prerender_url(),
718 entry->referrer(), 752 entry->referrer(),
719 entry->origin(), 753 entry->origin(),
720 entry->experiment_id()); 754 entry->experiment_id());
721 if (dummy_replacement_prerender_contents && 755 if (dummy_replacement_prerender_contents &&
722 dummy_replacement_prerender_contents->Init()) { 756 dummy_replacement_prerender_contents->Init()) {
723 dummy_replacement_prerender_contents-> 757 dummy_replacement_prerender_contents->
724 AddAliasURLsFromOtherPrerenderContents(entry); 758 AddAliasURLsFromOtherPrerenderContents(entry);
759 dummy_replacement_prerender_contents->set_match_complete_status(
760 PrerenderContents::MATCH_COMPLETE_REPLACEMENT);
725 it->contents_ = dummy_replacement_prerender_contents; 761 it->contents_ = dummy_replacement_prerender_contents;
726 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY);
727 swapped_in_dummy_replacement = true; 762 swapped_in_dummy_replacement = true;
728 } 763 }
729 } 764 }
730 } 765 }
731 if (!swapped_in_dummy_replacement) 766 if (!swapped_in_dummy_replacement)
732 prerender_list_.erase(it); 767 prerender_list_.erase(it);
733 break; 768 break;
734 } 769 }
735 } 770 }
736 AddToHistory(entry); 771 AddToHistory(entry);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { 1127 void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
1093 DeleteOldTabContents(); 1128 DeleteOldTabContents();
1094 while (!prerender_list_.empty()) { 1129 while (!prerender_list_.empty()) {
1095 PrerenderContentsData data = prerender_list_.front(); 1130 PrerenderContentsData data = prerender_list_.front();
1096 prerender_list_.pop_front(); 1131 prerender_list_.pop_front();
1097 data.contents_->Destroy(final_status); 1132 data.contents_->Destroy(final_status);
1098 } 1133 }
1099 DeletePendingDeleteEntries(); 1134 DeletePendingDeleteEntries();
1100 } 1135 }
1101 1136
1137 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus(
1138 Origin origin,
1139 uint8 experiment_id,
1140 PrerenderContents::MatchCompleteStatus mc_status,
1141 FinalStatus final_status) const {
1142 histograms_->RecordFinalStatus(origin,
1143 experiment_id,
1144 mc_status,
1145 final_status);
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(
1152 origin, experiment_id,
1153 PrerenderContents::MATCH_COMPLETE_DEFAULT,
1154 final_status);
1106 } 1155 }
1107 1156
1157
1108 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( 1158 PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
1109 int render_process_id) { 1159 int render_process_id) {
1110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1111 content::RenderProcessHost* render_process_host = 1161 content::RenderProcessHost* render_process_host =
1112 content::RenderProcessHost::FromID(render_process_id); 1162 content::RenderProcessHost::FromID(render_process_id);
1113 // Each render process is guaranteed to only hold RenderViews owned by the 1163 // Each render process is guaranteed to only hold RenderViews owned by the
1114 // same BrowserContext. This is enforced by 1164 // same BrowserContext. This is enforced by
1115 // RenderProcessHost::GetExistingProcessHost. 1165 // RenderProcessHost::GetExistingProcessHost.
1116 if (!render_process_host || !render_process_host->GetBrowserContext()) 1166 if (!render_process_host || !render_process_host->GetBrowserContext())
1117 return NULL; 1167 return NULL;
1118 Profile* profile = Profile::FromBrowserContext( 1168 Profile* profile = Profile::FromBrowserContext(
1119 render_process_host->GetBrowserContext()); 1169 render_process_host->GetBrowserContext());
1120 if (!profile) 1170 if (!profile)
1121 return NULL; 1171 return NULL;
1122 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1172 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1123 } 1173 }
1124 1174
1125 } // namespace prerender 1175 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698