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

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

Issue 11316311: Make PrerenderHandle an observer of PrerenderContents. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix windows build Created 8 years 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 <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 break; 216 break;
217 default: 217 default:
218 break; 218 break;
219 } 219 }
220 } 220 }
221 221
222 PrerenderManager::~PrerenderManager() { 222 PrerenderManager::~PrerenderManager() {
223 // The earlier call to ProfileKeyedService::Shutdown() should have emptied 223 // The earlier call to ProfileKeyedService::Shutdown() should have emptied
224 // these vectors already. 224 // these vectors already.
225 DCHECK(active_prerenders_.empty()); 225 DCHECK(active_prerenders_.empty());
226 DCHECK(pending_prerenders_.empty());
227 DCHECK(to_delete_prerenders_.empty()); 226 DCHECK(to_delete_prerenders_.empty());
228 } 227 }
229 228
230 void PrerenderManager::Shutdown() { 229 void PrerenderManager::Shutdown() {
231 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); 230 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN);
232 STLDeleteElements(&prerender_conditions_); 231 STLDeleteElements(&prerender_conditions_);
233 on_close_tab_contents_deleters_.clear(); 232 on_close_tab_contents_deleters_.clear();
234 // Must happen before |profile_| is set to NULL as 233 // Must happen before |profile_| is set to NULL as
235 // |local_predictor_| accesses it. 234 // |local_predictor_| accesses it.
236 if (local_predictor_) 235 if (local_predictor_)
237 local_predictor_->Shutdown(); 236 local_predictor_->Shutdown();
238 profile_ = NULL; 237 profile_ = NULL;
239 238
240 DCHECK(active_prerenders_.empty()); 239 DCHECK(active_prerenders_.empty());
241 pending_prerenders_.clear();
242 } 240 }
243 241
244 PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender( 242 PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender(
245 int process_id, 243 int process_id,
246 int route_id, 244 int route_id,
247 const GURL& url, 245 const GURL& url,
248 const content::Referrer& referrer, 246 const content::Referrer& referrer,
249 const gfx::Size& size) { 247 const gfx::Size& size) {
250 #if defined(OS_ANDROID) 248 #if defined(OS_ANDROID)
251 // TODO(jcivelli): http://crbug.com/113322 We should have an option to disable 249 // TODO(jcivelli): http://crbug.com/113322 We should have an option to disable
(...skipping 19 matching lines...) Expand all
271 session_storage_namespace = 269 session_storage_namespace =
272 source_web_contents->GetController() 270 source_web_contents->GetController()
273 .GetDefaultSessionStorageNamespace(); 271 .GetDefaultSessionStorageNamespace();
274 } 272 }
275 273
276 if (PrerenderData* parent_prerender_data = 274 if (PrerenderData* parent_prerender_data =
277 FindPrerenderDataForChildAndRoute(process_id, route_id)) { 275 FindPrerenderDataForChildAndRoute(process_id, route_id)) {
278 // Instead of prerendering from inside of a running prerender, we will defer 276 // Instead of prerendering from inside of a running prerender, we will defer
279 // this request until its launcher is made visible. 277 // this request until its launcher is made visible.
280 if (PrerenderContents* contents = parent_prerender_data->contents()) { 278 if (PrerenderContents* contents = parent_prerender_data->contents()) {
281 pending_prerenders_.push_back(new PrerenderData(this));
282 PrerenderHandle* prerender_handle = 279 PrerenderHandle* prerender_handle =
283 new PrerenderHandle(pending_prerenders_.back()); 280 new PrerenderHandle(static_cast<PrerenderData*>(NULL));
284 DCHECK(prerender_handle->IsPending());
285
286 scoped_ptr<PrerenderContents::PendingPrerenderInfo> 281 scoped_ptr<PrerenderContents::PendingPrerenderInfo>
287 pending_prerender_info(new PrerenderContents::PendingPrerenderInfo( 282 pending_prerender_info(new PrerenderContents::PendingPrerenderInfo(
288 prerender_handle->weak_ptr_factory_.GetWeakPtr(), 283 prerender_handle->weak_ptr_factory_.GetWeakPtr(),
289 origin, url, referrer, size)); 284 origin, url, referrer, size));
290 285
291 contents->AddPendingPrerender(pending_prerender_info.Pass()); 286 contents->AddPendingPrerender(pending_prerender_info.Pass());
292 return prerender_handle; 287 return prerender_handle;
293 } 288 }
294 } 289 }
295 290
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 CleanUpOldNavigations(); 843 CleanUpOldNavigations();
849 } 844 }
850 845
851 // protected 846 // protected
852 struct PrerenderManager::PrerenderData::OrderByExpiryTime { 847 struct PrerenderManager::PrerenderData::OrderByExpiryTime {
853 bool operator()(const PrerenderData* a, const PrerenderData* b) const { 848 bool operator()(const PrerenderData* a, const PrerenderData* b) const {
854 return a->expiry_time() < b->expiry_time(); 849 return a->expiry_time() < b->expiry_time();
855 } 850 }
856 }; 851 };
857 852
858 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager)
859 : manager_(manager), contents_(NULL), handle_count_(0) {
860 }
861
862 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager, 853 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager,
863 PrerenderContents* contents, 854 PrerenderContents* contents,
864 base::TimeTicks expiry_time) 855 base::TimeTicks expiry_time)
865 : manager_(manager), 856 : manager_(manager),
866 contents_(contents), 857 contents_(contents),
867 handle_count_(0), 858 handle_count_(0),
868 expiry_time_(expiry_time) { 859 expiry_time_(expiry_time) {
869 } 860 }
870 861
871 PrerenderManager::PrerenderData::~PrerenderData() { 862 PrerenderManager::PrerenderData::~PrerenderData() {
872 } 863 }
873 864
874 void PrerenderManager::PrerenderData::MakeIntoMatchCompleteReplacement() { 865 void PrerenderManager::PrerenderData::MakeIntoMatchCompleteReplacement() {
875 DCHECK(contents_); 866 DCHECK(contents_);
876 contents_->set_match_complete_status( 867 contents_->set_match_complete_status(
877 PrerenderContents::MATCH_COMPLETE_REPLACED); 868 PrerenderContents::MATCH_COMPLETE_REPLACED);
878 PrerenderData* to_delete = new PrerenderData(manager_, contents_.release(), 869 PrerenderData* to_delete = new PrerenderData(manager_, contents_.release(),
879 expiry_time_); 870 expiry_time_);
880 contents_.reset(to_delete->contents_->CreateMatchCompleteReplacement()); 871 contents_.reset(to_delete->contents_->CreateMatchCompleteReplacement());
881 manager_->to_delete_prerenders_.push_back(to_delete); 872 manager_->to_delete_prerenders_.push_back(to_delete);
882 } 873 }
883 874
884 void PrerenderManager::PrerenderData::OnNewHandle() { 875 void PrerenderManager::PrerenderData::OnNewHandle(PrerenderHandle* handle) {
885 DCHECK(contents_ || handle_count_ == 0) <<
886 "Cannot create multiple handles to a pending prerender.";
887 ++handle_count_; 876 ++handle_count_;
877 if (contents_)
mmenke 2012/12/06 22:22:15 contents_ can no longer be null.
gavinp 2012/12/10 17:55:10 Done.
878 contents_->AddObserver(handle);
888 } 879 }
889 880
890 void PrerenderManager::PrerenderData::OnNavigateAwayByHandle() { 881 void PrerenderManager::PrerenderData::OnNavigateAwayByHandle(
891 if (!contents_) { 882 PrerenderHandle* handle) {
892 DCHECK_EQ(1, handle_count_); 883 DCHECK_LT(0, handle_count_);
893 // Pending prerenders are not maintained in the active_prerenders_, so they 884 // We intentionally don't decrement the handle count here, so that the
894 // will not get normal expiry. Since this prerender hasn't even been 885 // prerender won't be canceled until it times out.
895 // launched yet, and it's held by a page that is being prerendered, we will 886 manager_->SourceNavigatedAway(this);
896 // just delete it.
897 manager_->DestroyPendingPrerenderData(this);
898 } else {
899 DCHECK_LE(0, handle_count_);
900 // We intentionally don't decrement the handle count here, so that the
901 // prerender won't be canceled until it times out.
902 manager_->SourceNavigatedAway(this);
903 }
904 } 887 }
905 888
906 void PrerenderManager::PrerenderData::OnCancelByHandle() { 889 void PrerenderManager::PrerenderData::OnCancelByHandle(
890 PrerenderHandle* handle) {
mmenke 2012/12/06 22:22:15 Why do we need the handle here? Just for consiste
gavinp 2012/12/10 17:55:10 Just for consistency.
907 DCHECK_LE(1, handle_count_); 891 DCHECK_LE(1, handle_count_);
908 DCHECK(contents_ || handle_count_ == 1); 892 DCHECK(contents_ || handle_count_ == 1)
893 << "Pending prerenders should never have multiple prerenders";
909 894
910 if (--handle_count_ == 0) { 895 if (--handle_count_ == 0) {
911 if (contents_) { 896 if (contents_) {
mmenke 2012/12/06 22:22:15 contents_ can't be null.
gavinp 2012/12/10 17:55:10 Done.
912 // This will eventually remove this object from active_prerenders_. 897 // This will eventually remove this object from active_prerenders_.
913 contents_->Destroy(FINAL_STATUS_CANCELLED); 898 contents_->Destroy(FINAL_STATUS_CANCELLED);
914 } else {
915 manager_->DestroyPendingPrerenderData(this);
916 } 899 }
917 } 900 }
918 } 901 }
919 902
920 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { 903 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() {
921 return contents_.release(); 904 return contents_.release();
922 } 905 }
923 906
924 void PrerenderManager::SetPrerenderContentsFactory( 907 void PrerenderManager::SetPrerenderContentsFactory(
925 PrerenderContents::Factory* prerender_contents_factory) { 908 PrerenderContents::Factory* prerender_contents_factory) {
926 DCHECK(CalledOnValidThread()); 909 DCHECK(CalledOnValidThread());
927 prerender_contents_factory_.reset(prerender_contents_factory); 910 prerender_contents_factory_.reset(prerender_contents_factory);
928 } 911 }
929 912
930 void PrerenderManager::StartPendingPrerenders( 913 void PrerenderManager::StartPendingPrerenders(
931 const int process_id, 914 const int process_id,
932 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders, 915 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders,
933 content::SessionStorageNamespace* session_storage_namespace) { 916 content::SessionStorageNamespace* session_storage_namespace) {
934 for (ScopedVector<PrerenderContents::PendingPrerenderInfo>::iterator 917 for (ScopedVector<PrerenderContents::PendingPrerenderInfo>::iterator
935 it = pending_prerenders->begin(); 918 it = pending_prerenders->begin();
936 it != pending_prerenders->end(); ++it) { 919 it != pending_prerenders->end(); ++it) {
937 PrerenderContents::PendingPrerenderInfo* info = *it; 920 PrerenderContents::PendingPrerenderInfo* info = *it;
938 PrerenderHandle* existing_prerender_handle = 921 PrerenderHandle* existing_prerender_handle =
939 info->weak_prerender_handle.get(); 922 info->weak_prerender_handle.get();
940 if (!existing_prerender_handle || !existing_prerender_handle->IsValid()) 923 if (!existing_prerender_handle)
924 continue;
925 if (existing_prerender_handle->has_been_canceled())
941 continue; 926 continue;
942 927
943 DCHECK(existing_prerender_handle->IsPending()); 928 DCHECK(!existing_prerender_handle->IsValid());
944 DCHECK(process_id == -1 || session_storage_namespace); 929 DCHECK(process_id == -1 || session_storage_namespace);
945 930
946 scoped_ptr<PrerenderHandle> swap_prerender_handle(AddPrerender( 931 scoped_ptr<PrerenderHandle> new_prerender_handle(AddPrerender(
947 info->origin, process_id, 932 info->origin, process_id,
948 info->url, info->referrer, info->size, 933 info->url, info->referrer, info->size,
949 session_storage_namespace)); 934 session_storage_namespace));
mmenke 2012/12/07 16:46:08 optional (Or feel free to think about in a later C
gavinp 2012/12/10 17:55:10 Definitely a good idea, and I'm definitely punting
950 if (swap_prerender_handle.get()) { 935 if (new_prerender_handle.get()) {
mmenke 2012/12/07 16:46:08 nit: Can remove the .get() while you're here.
gavinp 2012/12/10 17:55:10 enne is Awesome! Done.
951 // AddPrerender has returned a new prerender handle to us. We want to make 936 // AddPrerender has returned a new prerender handle to us. We want to make
952 // |existing_prerender_handle| active, so swap the underlying 937 // |existing_prerender_handle| active, so move the underlying
953 // PrerenderData between the two handles, and delete our old handle (which 938 // PrerenderData to our new handle.
954 // will release our entry in the pending_prerender_list_). 939 existing_prerender_handle->AdoptPrerenderDataFrom(
955 existing_prerender_handle->SwapPrerenderDataWith( 940 new_prerender_handle.get());
956 swap_prerender_handle.get());
957 swap_prerender_handle->OnCancel();
958 continue; 941 continue;
959 } 942 }
mmenke 2012/12/07 16:46:08 Random comment for the future - if a prerender is
gavinp 2012/12/13 13:38:03 I'm going to go with no. The launcher has no promi
960
961 // We could not start our Prerender. Canceling the existing handle will make
962 // it return false for PrerenderHandle::IsPending(), and will release the
963 // PrerenderData from pending_prerender_list_.
964 existing_prerender_handle->OnCancel();
965 } 943 }
966 } 944 }
967 945
968 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { 946 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) {
969 // The expiry time of our prerender data will likely change because of 947 // The expiry time of our prerender data will likely change because of
970 // this navigation. This requires a resort of active_prerenders_. 948 // this navigation. This requires a resort of active_prerenders_.
971 ScopedVector<PrerenderData>::iterator it = 949 ScopedVector<PrerenderData>::iterator it =
972 std::find(active_prerenders_.begin(), active_prerenders_.end(), 950 std::find(active_prerenders_.begin(), active_prerenders_.end(),
973 prerender_data); 951 prerender_data);
974 if (it == active_prerenders_.end()) 952 if (it == active_prerenders_.end())
975 return; 953 return;
976 954
977 (*it)->set_expiry_time( 955 (*it)->set_expiry_time(
978 std::min((*it)->expiry_time(), 956 std::min((*it)->expiry_time(),
979 GetExpiryTimeForNavigatedAwayPrerender())); 957 GetExpiryTimeForNavigatedAwayPrerender()));
980 SortActivePrerenders(); 958 SortActivePrerenders();
981 } 959 }
982 960
983 void PrerenderManager::DestroyPendingPrerenderData(
984 PrerenderData* pending_prerender_data) {
985 ScopedVector<PrerenderData>::iterator it =
986 std::find(pending_prerenders_.begin(), pending_prerenders_.end(),
987 pending_prerender_data);
988 if (it == pending_prerenders_.end())
989 return;
990 pending_prerenders_.erase(it);
991 }
992
993 // private 961 // private
994 PrerenderHandle* PrerenderManager::AddPrerender( 962 PrerenderHandle* PrerenderManager::AddPrerender(
995 Origin origin, 963 Origin origin,
996 int process_id, 964 int process_id,
997 const GURL& url_arg, 965 const GURL& url_arg,
998 const content::Referrer& referrer, 966 const content::Referrer& referrer,
999 const gfx::Size& size, 967 const gfx::Size& size,
1000 SessionStorageNamespace* session_storage_namespace) { 968 SessionStorageNamespace* session_storage_namespace) {
1001 DCHECK(CalledOnValidThread()); 969 DCHECK(CalledOnValidThread());
1002 970
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 if (!render_process_host || !render_process_host->GetBrowserContext()) 1325 if (!render_process_host || !render_process_host->GetBrowserContext())
1358 return NULL; 1326 return NULL;
1359 Profile* profile = Profile::FromBrowserContext( 1327 Profile* profile = Profile::FromBrowserContext(
1360 render_process_host->GetBrowserContext()); 1328 render_process_host->GetBrowserContext());
1361 if (!profile) 1329 if (!profile)
1362 return NULL; 1330 return NULL;
1363 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1331 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1364 } 1332 }
1365 1333
1366 } // namespace prerender 1334 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698