| 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/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 "GET", | 70 "GET", |
| 71 "HEAD", | 71 "HEAD", |
| 72 "OPTIONS", | 72 "OPTIONS", |
| 73 "POST", | 73 "POST", |
| 74 "TRACE", | 74 "TRACE", |
| 75 }; | 75 }; |
| 76 | 76 |
| 77 // Length of prerender history, for display in chrome://net-internals | 77 // Length of prerender history, for display in chrome://net-internals |
| 78 const int kHistoryLength = 100; | 78 const int kHistoryLength = 100; |
| 79 | 79 |
| 80 // Indicates whether a Prerender has been cancelled such that we need | |
| 81 // a dummy replacement for the purpose of recording the correct PPLT for | |
| 82 // the Match Complete case. | |
| 83 | |
| 84 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) { | |
| 85 return final_status != FINAL_STATUS_USED && | |
| 86 final_status != FINAL_STATUS_TIMED_OUT && | |
| 87 final_status != FINAL_STATUS_EVICTED && | |
| 88 final_status != FINAL_STATUS_MANAGER_SHUTDOWN && | |
| 89 final_status != FINAL_STATUS_WINDOW_OPENER && | |
| 90 final_status != FINAL_STATUS_FRAGMENT_MISMATCH && | |
| 91 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && | |
| 92 final_status != FINAL_STATUS_CANCELLED && | |
| 93 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; | |
| 94 } | |
| 95 | |
| 96 } // namespace | 80 } // namespace |
| 97 | 81 |
| 98 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { | 82 class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { |
| 99 public: | 83 public: |
| 100 OnCloseTabContentsDeleter(PrerenderManager* manager, | 84 OnCloseTabContentsDeleter(PrerenderManager* manager, |
| 101 TabContentsWrapper* tab) | 85 TabContentsWrapper* tab) |
| 102 : manager_(manager), | 86 : manager_(manager), |
| 103 tab_(tab) { | 87 tab_(tab) { |
| 104 tab_->tab_contents()->set_delegate(this); | 88 tab_->tab_contents()->set_delegate(this); |
| 105 } | 89 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 123 |
| 140 // static | 124 // static |
| 141 bool PrerenderManager::IsPrerenderingPossible() { | 125 bool PrerenderManager::IsPrerenderingPossible() { |
| 142 return GetMode() == PRERENDER_MODE_ENABLED || | 126 return GetMode() == PRERENDER_MODE_ENABLED || |
| 143 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || | 127 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || |
| 144 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP || | 128 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP || |
| 145 GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; | 129 GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; |
| 146 } | 130 } |
| 147 | 131 |
| 148 // static | 132 // static |
| 149 bool PrerenderManager::ActuallyPrerendering() { | |
| 150 return IsPrerenderingPossible() && !IsControlGroup(); | |
| 151 } | |
| 152 | |
| 153 // static | |
| 154 bool PrerenderManager::IsControlGroup() { | 133 bool PrerenderManager::IsControlGroup() { |
| 155 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; | 134 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; |
| 156 } | 135 } |
| 157 | 136 |
| 158 // static | 137 // static |
| 159 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { | 138 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { |
| 160 // method has been canonicalized to upper case at this point so we can just | 139 // method has been canonicalized to upper case at this point so we can just |
| 161 // compare them. | 140 // compare them. |
| 162 DCHECK_EQ(method, StringToUpperASCII(method)); | 141 DCHECK_EQ(method, StringToUpperASCII(method)); |
| 163 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { | 142 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 // No unload handler to run, so delete asap. | 643 // No unload handler to run, so delete asap. |
| 665 ScheduleDeleteOldTabContents(old_tab_contents, NULL); | 644 ScheduleDeleteOldTabContents(old_tab_contents, NULL); |
| 666 } | 645 } |
| 667 | 646 |
| 668 // TODO(cbentzel): Should prerender_contents move to the pending delete | 647 // TODO(cbentzel): Should prerender_contents move to the pending delete |
| 669 // list, instead of deleting directly here? | 648 // list, instead of deleting directly here? |
| 670 AddToHistory(prerender_contents.get()); | 649 AddToHistory(prerender_contents.get()); |
| 671 return true; | 650 return true; |
| 672 } | 651 } |
| 673 | 652 |
| 674 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry, | 653 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { |
| 675 FinalStatus final_status) { | |
| 676 DCHECK(CalledOnValidThread()); | 654 DCHECK(CalledOnValidThread()); |
| 677 DCHECK(entry); | |
| 678 DCHECK(!IsPendingDelete(entry)); | 655 DCHECK(!IsPendingDelete(entry)); |
| 679 | |
| 680 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); | 656 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); |
| 681 it != prerender_list_.end(); | 657 it != prerender_list_.end(); |
| 682 ++it) { | 658 ++it) { |
| 683 if (it->contents_ == entry) { | 659 if (it->contents_ == entry) { |
| 684 bool swapped_in_dummy_replacement = false; | 660 prerender_list_.erase(it); |
| 685 | |
| 686 // If this PrerenderContents is being deleted due to a cancellation, | |
| 687 // we need to create a dummy replacement for PPLT accounting purposes | |
| 688 // for the Match Complete group. | |
| 689 // This is the case if the cancellation is for any reason that would not | |
| 690 // occur in the control group case. | |
| 691 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { | |
| 692 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. | |
| 693 // However, what if new conditions are added and | |
| 694 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure | |
| 695 // what's the best thing to do here. For now, I will just check whether | |
| 696 // we are actually prerendering. | |
| 697 if (ActuallyPrerendering()) { | |
| 698 PrerenderContents* dummy_replacement_prerender_contents = | |
| 699 CreatePrerenderContents( | |
| 700 entry->prerender_url(), | |
| 701 entry->referrer(), | |
| 702 entry->origin(), | |
| 703 entry->experiment_id()); | |
| 704 if (dummy_replacement_prerender_contents && | |
| 705 dummy_replacement_prerender_contents->Init()) { | |
| 706 it->contents_ = dummy_replacement_prerender_contents; | |
| 707 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY); | |
| 708 swapped_in_dummy_replacement = true; | |
| 709 } | |
| 710 } | |
| 711 } | |
| 712 if (!swapped_in_dummy_replacement) | |
| 713 prerender_list_.erase(it); | |
| 714 break; | 661 break; |
| 715 } | 662 } |
| 716 } | 663 } |
| 717 AddToHistory(entry); | 664 AddToHistory(entry); |
| 718 pending_delete_list_.push_back(entry); | 665 pending_delete_list_.push_back(entry); |
| 719 | 666 |
| 720 // Destroy the old TabContents relatively promptly to reduce resource usage, | 667 // Destroy the old TabContents relatively promptly to reduce resource usage, |
| 721 // and in the case of HTML5 media, reduce the change of playing any sound. | 668 // and in the case of HTML5 media, reduce the change of playing any sound. |
| 722 PostCleanupTask(); | 669 PostCleanupTask(); |
| 723 } | 670 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 const GURL& url) { | 722 const GURL& url) { |
| 776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 777 PrerenderManager* prerender_manager = | 724 PrerenderManager* prerender_manager = |
| 778 PrerenderManagerFactory::GetForProfile( | 725 PrerenderManagerFactory::GetForProfile( |
| 779 Profile::FromBrowserContext(tab_contents->browser_context())); | 726 Profile::FromBrowserContext(tab_contents->browser_context())); |
| 780 if (!prerender_manager) | 727 if (!prerender_manager) |
| 781 return; | 728 return; |
| 782 if (!prerender_manager->is_enabled()) | 729 if (!prerender_manager->is_enabled()) |
| 783 return; | 730 return; |
| 784 bool was_prerender = | 731 bool was_prerender = |
| 785 prerender_manager->IsTabContentsPrerendered(tab_contents); | 732 ((mode_ == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP && |
| 786 bool was_complete_prerender = was_prerender || | 733 prerender_manager->WouldTabContentsBePrerendered(tab_contents)) || |
| 787 prerender_manager->WouldTabContentsBePrerendered(tab_contents); | 734 (mode_ == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP && |
| 735 prerender_manager->IsTabContentsPrerendered(tab_contents))); |
| 788 prerender_manager->histograms_->RecordPerceivedPageLoadTime( | 736 prerender_manager->histograms_->RecordPerceivedPageLoadTime( |
| 789 perceived_page_load_time, was_prerender, was_complete_prerender, url); | 737 perceived_page_load_time, was_prerender, url); |
| 790 } | 738 } |
| 791 | 739 |
| 792 bool PrerenderManager::is_enabled() const { | 740 bool PrerenderManager::is_enabled() const { |
| 793 DCHECK(CalledOnValidThread()); | 741 DCHECK(CalledOnValidThread()); |
| 794 if (!enabled_) | 742 if (!enabled_) |
| 795 return false; | 743 return false; |
| 796 for (std::list<const PrerenderCondition*>::const_iterator it = | 744 for (std::list<const PrerenderCondition*>::const_iterator it = |
| 797 prerender_conditions_.begin(); | 745 prerender_conditions_.begin(); |
| 798 it != prerender_conditions_.end(); | 746 it != prerender_conditions_.end(); |
| 799 ++it) { | 747 ++it) { |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 if (!render_process_host || !render_process_host->browser_context()) | 1059 if (!render_process_host || !render_process_host->browser_context()) |
| 1112 return NULL; | 1060 return NULL; |
| 1113 Profile* profile = Profile::FromBrowserContext( | 1061 Profile* profile = Profile::FromBrowserContext( |
| 1114 render_process_host->browser_context()); | 1062 render_process_host->browser_context()); |
| 1115 if (!profile) | 1063 if (!profile) |
| 1116 return NULL; | 1064 return NULL; |
| 1117 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); | 1065 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); |
| 1118 } | 1066 } |
| 1119 | 1067 |
| 1120 } // namespace prerender | 1068 } // namespace prerender |
| OLD | NEW |