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

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) {
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 &&
99 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; 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;
100 } 115 }
101 116
102 } // namespace 117 } // namespace
103 118
104 class PrerenderManager::OnCloseTabContentsDeleter 119 class PrerenderManager::OnCloseTabContentsDeleter
105 : public content::WebContentsDelegate, 120 : public content::WebContentsDelegate,
106 public base::SupportsWeakPtr< 121 public base::SupportsWeakPtr<
107 PrerenderManager::OnCloseTabContentsDeleter> { 122 PrerenderManager::OnCloseTabContentsDeleter> {
108 public: 123 public:
109 OnCloseTabContentsDeleter(PrerenderManager* manager, 124 OnCloseTabContentsDeleter(PrerenderManager* manager,
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!prerender_contents || !prerender_contents->Init()) 445 if (!prerender_contents || !prerender_contents->Init())
431 return false; 446 return false;
432 447
433 histograms_->RecordPrerenderStarted(origin); 448 histograms_->RecordPrerenderStarted(origin);
434 449
435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 450 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 451 PrerenderContentsData data(prerender_contents, GetCurrentTime());
437 452
438 prerender_list_.push_back(data); 453 prerender_list_.push_back(data);
439 454
440 if (IsControlGroup()) { 455 if (!IsControlGroup()) {
441 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
442 } else {
443 last_prerender_start_time_ = GetCurrentTimeTicks(); 456 last_prerender_start_time_ = GetCurrentTimeTicks();
444 data.contents_->StartPrerendering(source_render_view_host, 457 data.contents_->StartPrerendering(source_render_view_host,
445 session_storage_namespace); 458 session_storage_namespace);
446 } 459 }
447 while (prerender_list_.size() > config_.max_elements) { 460 while (prerender_list_.size() > config_.max_elements) {
448 data = prerender_list_.front(); 461 data = prerender_list_.front();
449 prerender_list_.pop_front(); 462 prerender_list_.pop_front();
450 data.contents_->Destroy(FINAL_STATUS_EVICTED); 463 data.contents_->Destroy(FINAL_STATUS_EVICTED);
451 } 464 }
452 StartSchedulingPeriodicCleanups(); 465 StartSchedulingPeriodicCleanups();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 540 }
528 } 541 }
529 // Entry not found. 542 // Entry not found.
530 return NULL; 543 return NULL;
531 } 544 }
532 545
533 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { 546 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) {
534 return GetEntryButNotSpecifiedWC(url, NULL); 547 return GetEntryButNotSpecifiedWC(url, NULL);
535 } 548 }
536 549
550 void PrerenderManager::DestroyAndMarkMatchCompleteAsUsed(
551 PrerenderContents* prerender_contents,
552 FinalStatus final_status) {
553 prerender_contents->set_match_complete_status(
554 PrerenderContents::MATCH_COMPLETE_REPLACED);
555 histograms_->RecordFinalStatus(prerender_contents->origin(),
556 prerender_contents->experiment_id(),
557 PrerenderContents::MATCH_COMPLETE_REPLACEMENT,
558 FINAL_STATUS_WOULD_HAVE_BEEN_USED);
559 prerender_contents->Destroy(final_status);
560 }
561
537 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, 562 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
538 const GURL& url, 563 const GURL& url,
539 const GURL& opener_url) { 564 const GURL& opener_url) {
540 DCHECK(CalledOnValidThread()); 565 DCHECK(CalledOnValidThread());
541 RecordNavigation(url); 566 RecordNavigation(url);
542 567
543 scoped_ptr<PrerenderContents> prerender_contents( 568 scoped_ptr<PrerenderContents> prerender_contents(
544 GetEntryButNotSpecifiedWC(url, web_contents)); 569 GetEntryButNotSpecifiedWC(url, web_contents));
545 if (prerender_contents.get() == NULL) 570 if (prerender_contents.get() == NULL)
546 return false; 571 return false;
(...skipping 15 matching lines...) Expand all
562 if (url_matches && url.ref() != matching_url.ref()) { 587 if (url_matches && url.ref() != matching_url.ref()) {
563 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH); 588 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH);
564 return false; 589 return false;
565 } 590 }
566 591
567 // If we are just in the control group (which can be detected by noticing 592 // 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 593 // 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. 594 // would be showing a prerendered contents, but otherwise, don't do anything.
570 if (!prerender_contents->prerendering_has_started()) { 595 if (!prerender_contents->prerendering_has_started()) {
571 MarkWebContentsAsWouldBePrerendered(web_contents); 596 MarkWebContentsAsWouldBePrerendered(web_contents);
597 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
572 return false; 598 return false;
573 } 599 }
574 600
575 // Don't use prerendered pages if debugger is attached to the tab. 601 // Don't use prerendered pages if debugger is attached to the tab.
576 // See http://crbug.com/98541 602 // See http://crbug.com/98541
577 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { 603 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) {
578 prerender_contents.release()->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED); 604 DestroyAndMarkMatchCompleteAsUsed(prerender_contents.release(),
605 FINAL_STATUS_DEVTOOLS_ATTACHED);
579 return false; 606 return false;
580 } 607 }
581 608
582 // If the prerendered page is in the middle of a cross-site navigation, 609 // 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. 610 // don't swap it in because there isn't a good way to merge histories.
584 if (prerender_contents->IsCrossSiteNavigationPending()) { 611 if (prerender_contents->IsCrossSiteNavigationPending()) {
585 prerender_contents.release()->Destroy( 612 DestroyAndMarkMatchCompleteAsUsed(
613 prerender_contents.release(),
586 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); 614 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
587 return false; 615 return false;
588 } 616 }
589 617
590 // If the session storage namespaces don't match, cancel the prerender. 618 // If the session storage namespaces don't match, cancel the prerender.
591 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost(); 619 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost();
592 RenderViewHost* new_render_view_host = 620 RenderViewHost* new_render_view_host =
593 prerender_contents->prerender_contents()->web_contents()-> 621 prerender_contents->prerender_contents()->web_contents()->
594 GetRenderViewHost(); 622 GetRenderViewHost();
595 DCHECK(old_render_view_host); 623 DCHECK(old_render_view_host);
596 DCHECK(new_render_view_host); 624 DCHECK(new_render_view_host);
597 if (old_render_view_host->session_storage_namespace() != 625 if (old_render_view_host->session_storage_namespace() !=
598 new_render_view_host->session_storage_namespace()) { 626 new_render_view_host->session_storage_namespace()) {
599 prerender_contents.release()->Destroy( 627 DestroyAndMarkMatchCompleteAsUsed(
628 prerender_contents.release(),
600 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH); 629 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH);
601 return false; 630 return false;
602 } 631 }
603 632
604 // If we don't want to use prerenders at all, we are done. 633 // If we don't want to use prerenders at all, we are done.
605 // For bookkeeping purposes, we need to mark this TabContents to 634 // For bookkeeping purposes, we need to mark this TabContents to
606 // reflect that it would have been prerendered. 635 // reflect that it would have been prerendered.
607 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { 636 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
608 MarkWebContentsAsWouldBePrerendered(web_contents); 637 MarkWebContentsAsWouldBePrerendered(web_contents);
609 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP); 638 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
610 return false; 639 return false;
611 } 640 }
612 641
613 int child_id, route_id; 642 int child_id, route_id;
614 CHECK(prerender_contents->GetChildId(&child_id)); 643 CHECK(prerender_contents->GetChildId(&child_id));
615 CHECK(prerender_contents->GetRouteId(&route_id)); 644 CHECK(prerender_contents->GetRouteId(&route_id));
616 645
617 // Try to set the prerendered page as used, so any subsequent attempts to 646 // 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 647 // cancel on other threads will fail. If this fails because the prerender
619 // was already cancelled, possibly on another thread, fail. 648 // 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(); 727 it != prerender_list_.end();
699 ++it) { 728 ++it) {
700 if (it->contents_ == entry) { 729 if (it->contents_ == entry) {
701 bool swapped_in_dummy_replacement = false; 730 bool swapped_in_dummy_replacement = false;
702 731
703 // If this PrerenderContents is being deleted due to a cancellation, 732 // If this PrerenderContents is being deleted due to a cancellation,
704 // we need to create a dummy replacement for PPLT accounting purposes 733 // we need to create a dummy replacement for PPLT accounting purposes
705 // for the Match Complete group. 734 // for the Match Complete group.
706 // This is the case if the cancellation is for any reason that would not 735 // This is the case if the cancellation is for any reason that would not
707 // occur in the control group case. 736 // occur in the control group case.
708 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { 737 if (entry->match_complete_status() ==
738 PrerenderContents::MATCH_COMPLETE_DEFAULT &&
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_match_complete_status(
747 PrerenderContents::MATCH_COMPLETE_REPLACED);
715 PrerenderContents* dummy_replacement_prerender_contents = 748 PrerenderContents* dummy_replacement_prerender_contents =
716 CreatePrerenderContents( 749 CreatePrerenderContents(
717 entry->prerender_url(), 750 entry->prerender_url(),
718 entry->referrer(), 751 entry->referrer(),
719 entry->origin(), 752 entry->origin(),
720 entry->experiment_id()); 753 entry->experiment_id());
721 if (dummy_replacement_prerender_contents && 754 if (dummy_replacement_prerender_contents &&
722 dummy_replacement_prerender_contents->Init()) { 755 dummy_replacement_prerender_contents->Init()) {
723 dummy_replacement_prerender_contents-> 756 dummy_replacement_prerender_contents->
724 AddAliasURLsFromOtherPrerenderContents(entry); 757 AddAliasURLsFromOtherPrerenderContents(entry);
758 dummy_replacement_prerender_contents->set_match_complete_status(
759 PrerenderContents::MATCH_COMPLETE_REPLACEMENT);
725 it->contents_ = dummy_replacement_prerender_contents; 760 it->contents_ = dummy_replacement_prerender_contents;
726 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY);
727 swapped_in_dummy_replacement = true; 761 swapped_in_dummy_replacement = true;
728 } 762 }
729 } 763 }
730 } 764 }
731 if (!swapped_in_dummy_replacement) 765 if (!swapped_in_dummy_replacement)
732 prerender_list_.erase(it); 766 prerender_list_.erase(it);
733 break; 767 break;
734 } 768 }
735 } 769 }
736 AddToHistory(entry); 770 AddToHistory(entry);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { 1126 void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
1093 DeleteOldTabContents(); 1127 DeleteOldTabContents();
1094 while (!prerender_list_.empty()) { 1128 while (!prerender_list_.empty()) {
1095 PrerenderContentsData data = prerender_list_.front(); 1129 PrerenderContentsData data = prerender_list_.front();
1096 prerender_list_.pop_front(); 1130 prerender_list_.pop_front();
1097 data.contents_->Destroy(final_status); 1131 data.contents_->Destroy(final_status);
1098 } 1132 }
1099 DeletePendingDeleteEntries(); 1133 DeletePendingDeleteEntries();
1100 } 1134 }
1101 1135
1136 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus(
1137 Origin origin,
1138 uint8 experiment_id,
1139 PrerenderContents::MatchCompleteStatus mc_status,
1140 FinalStatus final_status) const {
1141 histograms_->RecordFinalStatus(origin,
1142 experiment_id,
1143 mc_status,
1144 final_status);
1145 }
1146
1102 void PrerenderManager::RecordFinalStatus(Origin origin, 1147 void PrerenderManager::RecordFinalStatus(Origin origin,
1103 uint8 experiment_id, 1148 uint8 experiment_id,
1104 FinalStatus final_status) const { 1149 FinalStatus final_status) const {
1105 histograms_->RecordFinalStatus(origin, experiment_id, final_status); 1150 RecordFinalStatusWithMatchCompleteStatus(
1151 origin, experiment_id,
1152 PrerenderContents::MATCH_COMPLETE_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
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | chrome/browser/prerender/prerender_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698