| OLD | NEW |
| 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 Loading... |
| 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_web_contents_deleters_.clear(); | 232 on_close_web_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 Loading... |
| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 prerender_contents->SetFinalStatus(FINAL_STATUS_USED); | 417 prerender_contents->SetFinalStatus(FINAL_STATUS_USED); |
| 423 | 418 |
| 424 RenderViewHost* new_render_view_host = | 419 RenderViewHost* new_render_view_host = |
| 425 prerender_contents->prerender_contents()->GetRenderViewHost(); | 420 prerender_contents->prerender_contents()->GetRenderViewHost(); |
| 426 new_render_view_host->Send( | 421 new_render_view_host->Send( |
| 427 new PrerenderMsg_SetIsPrerendering(new_render_view_host->GetRoutingID(), | 422 new PrerenderMsg_SetIsPrerendering(new_render_view_host->GetRoutingID(), |
| 428 false)); | 423 false)); |
| 429 | 424 |
| 430 // Start pending prerender requests from the PrerenderContents, if there are | 425 // Start pending prerender requests from the PrerenderContents, if there are |
| 431 // any. | 426 // any. |
| 432 prerender_contents->StartPendingPrerenders(); | 427 prerender_contents->PrepareForUse(); |
| 433 | 428 |
| 434 WebContents* new_web_contents = | 429 WebContents* new_web_contents = |
| 435 prerender_contents->ReleasePrerenderContents(); | 430 prerender_contents->ReleasePrerenderContents(); |
| 436 WebContents* old_web_contents = web_contents; | 431 WebContents* old_web_contents = web_contents; |
| 437 DCHECK(new_web_contents); | 432 DCHECK(new_web_contents); |
| 438 DCHECK(old_web_contents); | 433 DCHECK(old_web_contents); |
| 439 | 434 |
| 440 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); | 435 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); |
| 441 | 436 |
| 442 // Merge the browsing history. | 437 // Merge the browsing history. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 // for PPLT accounting purposes for the Match Complete group. This is the case | 489 // for PPLT accounting purposes for the Match Complete group. This is the case |
| 495 // if the cancellation is for any reason that would not occur in the control | 490 // if the cancellation is for any reason that would not occur in the control |
| 496 // group case. | 491 // group case. |
| 497 if (entry->prerendering_has_started() && | 492 if (entry->prerendering_has_started() && |
| 498 entry->match_complete_status() == | 493 entry->match_complete_status() == |
| 499 PrerenderContents::MATCH_COMPLETE_DEFAULT && | 494 PrerenderContents::MATCH_COMPLETE_DEFAULT && |
| 500 NeedMatchCompleteDummyForFinalStatus(final_status) && | 495 NeedMatchCompleteDummyForFinalStatus(final_status) && |
| 501 ActuallyPrerendering()) { | 496 ActuallyPrerendering()) { |
| 502 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. | 497 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. |
| 503 // However, what if new conditions are added and | 498 // However, what if new conditions are added and |
| 504 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure | 499 // NeedMatchCompleteDummyForFinalStatus is not being updated. Not sure |
| 505 // what's the best thing to do here. For now, I will just check whether | 500 // what's the best thing to do here. For now, I will just check whether |
| 506 // we are actually prerendering. | 501 // we are actually prerendering. |
| 507 (*it)->MakeIntoMatchCompleteReplacement(); | 502 (*it)->MakeIntoMatchCompleteReplacement(); |
| 508 } else { | 503 } else { |
| 509 to_delete_prerenders_.push_back(*it); | 504 to_delete_prerenders_.push_back(*it); |
| 510 active_prerenders_.weak_erase(it); | 505 active_prerenders_.weak_erase(it); |
| 511 } | 506 } |
| 512 | 507 |
| 513 // Destroy the old WebContents relatively promptly to reduce resource usage, | 508 // Destroy the old WebContents relatively promptly to reduce resource usage, |
| 514 // and in the case of HTML5 media, reduce the change of playing any sound. | 509 // and in the case of HTML5 media, reduce the chance of playing any sound. |
| 515 PostCleanupTask(); | 510 PostCleanupTask(); |
| 516 } | 511 } |
| 517 | 512 |
| 518 // static | 513 // static |
| 519 void PrerenderManager::RecordPerceivedPageLoadTime( | 514 void PrerenderManager::RecordPerceivedPageLoadTime( |
| 520 base::TimeDelta perceived_page_load_time, | 515 base::TimeDelta perceived_page_load_time, |
| 521 double fraction_plt_elapsed_at_swap_in, | 516 double fraction_plt_elapsed_at_swap_in, |
| 522 WebContents* web_contents, | 517 WebContents* web_contents, |
| 523 const GURL& url) { | 518 const GURL& url) { |
| 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 519 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 CleanUpOldNavigations(); | 839 CleanUpOldNavigations(); |
| 845 } | 840 } |
| 846 | 841 |
| 847 // protected | 842 // protected |
| 848 struct PrerenderManager::PrerenderData::OrderByExpiryTime { | 843 struct PrerenderManager::PrerenderData::OrderByExpiryTime { |
| 849 bool operator()(const PrerenderData* a, const PrerenderData* b) const { | 844 bool operator()(const PrerenderData* a, const PrerenderData* b) const { |
| 850 return a->expiry_time() < b->expiry_time(); | 845 return a->expiry_time() < b->expiry_time(); |
| 851 } | 846 } |
| 852 }; | 847 }; |
| 853 | 848 |
| 854 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager) | |
| 855 : manager_(manager), contents_(NULL), handle_count_(0) { | |
| 856 } | |
| 857 | |
| 858 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager, | 849 PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager, |
| 859 PrerenderContents* contents, | 850 PrerenderContents* contents, |
| 860 base::TimeTicks expiry_time) | 851 base::TimeTicks expiry_time) |
| 861 : manager_(manager), | 852 : manager_(manager), |
| 862 contents_(contents), | 853 contents_(contents), |
| 863 handle_count_(0), | 854 handle_count_(0), |
| 864 expiry_time_(expiry_time) { | 855 expiry_time_(expiry_time) { |
| 856 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); |
| 865 } | 857 } |
| 866 | 858 |
| 867 PrerenderManager::PrerenderData::~PrerenderData() { | 859 PrerenderManager::PrerenderData::~PrerenderData() { |
| 868 } | 860 } |
| 869 | 861 |
| 870 void PrerenderManager::PrerenderData::MakeIntoMatchCompleteReplacement() { | 862 void PrerenderManager::PrerenderData::MakeIntoMatchCompleteReplacement() { |
| 871 DCHECK(contents_); | 863 DCHECK(contents_); |
| 872 contents_->set_match_complete_status( | 864 contents_->set_match_complete_status( |
| 873 PrerenderContents::MATCH_COMPLETE_REPLACED); | 865 PrerenderContents::MATCH_COMPLETE_REPLACED); |
| 874 PrerenderData* to_delete = new PrerenderData(manager_, contents_.release(), | 866 PrerenderData* to_delete = new PrerenderData(manager_, contents_.release(), |
| 875 expiry_time_); | 867 expiry_time_); |
| 876 contents_.reset(to_delete->contents_->CreateMatchCompleteReplacement()); | 868 contents_.reset(to_delete->contents_->CreateMatchCompleteReplacement()); |
| 877 manager_->to_delete_prerenders_.push_back(to_delete); | 869 manager_->to_delete_prerenders_.push_back(to_delete); |
| 878 } | 870 } |
| 879 | 871 |
| 880 void PrerenderManager::PrerenderData::OnNewHandle() { | 872 void PrerenderManager::PrerenderData::OnHandleCreated(PrerenderHandle* handle) { |
| 881 DCHECK(contents_ || handle_count_ == 0) << | 873 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); |
| 882 "Cannot create multiple handles to a pending prerender."; | |
| 883 ++handle_count_; | 874 ++handle_count_; |
| 875 contents_->AddObserver(handle); |
| 884 } | 876 } |
| 885 | 877 |
| 886 void PrerenderManager::PrerenderData::OnNavigateAwayByHandle() { | 878 void PrerenderManager::PrerenderData::OnHandleNavigatedAway( |
| 887 if (!contents_) { | 879 PrerenderHandle* handle) { |
| 888 DCHECK_EQ(1, handle_count_); | 880 DCHECK_LT(0, handle_count_); |
| 889 // Pending prerenders are not maintained in the active_prerenders_, so they | 881 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); |
| 890 // will not get normal expiry. Since this prerender hasn't even been | 882 // We intentionally don't decrement the handle count here, so that the |
| 891 // launched yet, and it's held by a page that is being prerendered, we will | 883 // prerender won't be canceled until it times out. |
| 892 // just delete it. | 884 manager_->SourceNavigatedAway(this); |
| 893 manager_->DestroyPendingPrerenderData(this); | 885 } |
| 894 } else { | 886 |
| 895 DCHECK_LE(0, handle_count_); | 887 void PrerenderManager::PrerenderData::OnHandleCanceled( |
| 896 // We intentionally don't decrement the handle count here, so that the | 888 PrerenderHandle* handle) { |
| 897 // prerender won't be canceled until it times out. | 889 DCHECK_LT(0, handle_count_); |
| 898 manager_->SourceNavigatedAway(this); | 890 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); |
| 891 |
| 892 if (--handle_count_ == 0) { |
| 893 // This will eventually remove this object from active_prerenders_. |
| 894 contents_->Destroy(FINAL_STATUS_CANCELLED); |
| 899 } | 895 } |
| 900 } | 896 } |
| 901 | 897 |
| 902 void PrerenderManager::PrerenderData::OnCancelByHandle() { | |
| 903 DCHECK_LE(1, handle_count_); | |
| 904 DCHECK(contents_ || handle_count_ == 1); | |
| 905 | |
| 906 if (--handle_count_ == 0) { | |
| 907 if (contents_) { | |
| 908 // This will eventually remove this object from active_prerenders_. | |
| 909 contents_->Destroy(FINAL_STATUS_CANCELLED); | |
| 910 } else { | |
| 911 manager_->DestroyPendingPrerenderData(this); | |
| 912 } | |
| 913 } | |
| 914 } | |
| 915 | |
| 916 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { | 898 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { |
| 917 return contents_.release(); | 899 return contents_.release(); |
| 918 } | 900 } |
| 919 | 901 |
| 920 void PrerenderManager::SetPrerenderContentsFactory( | 902 void PrerenderManager::SetPrerenderContentsFactory( |
| 921 PrerenderContents::Factory* prerender_contents_factory) { | 903 PrerenderContents::Factory* prerender_contents_factory) { |
| 922 DCHECK(CalledOnValidThread()); | 904 DCHECK(CalledOnValidThread()); |
| 923 prerender_contents_factory_.reset(prerender_contents_factory); | 905 prerender_contents_factory_.reset(prerender_contents_factory); |
| 924 } | 906 } |
| 925 | 907 |
| 926 void PrerenderManager::StartPendingPrerenders( | 908 void PrerenderManager::StartPendingPrerenders( |
| 927 const int process_id, | 909 const int process_id, |
| 928 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders, | 910 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders, |
| 929 content::SessionStorageNamespace* session_storage_namespace) { | 911 content::SessionStorageNamespace* session_storage_namespace) { |
| 930 for (ScopedVector<PrerenderContents::PendingPrerenderInfo>::iterator | 912 for (ScopedVector<PrerenderContents::PendingPrerenderInfo>::iterator |
| 931 it = pending_prerenders->begin(); | 913 it = pending_prerenders->begin(); |
| 932 it != pending_prerenders->end(); ++it) { | 914 it != pending_prerenders->end(); ++it) { |
| 933 PrerenderContents::PendingPrerenderInfo* info = *it; | 915 PrerenderContents::PendingPrerenderInfo* info = *it; |
| 934 PrerenderHandle* existing_prerender_handle = | 916 PrerenderHandle* existing_prerender_handle = |
| 935 info->weak_prerender_handle.get(); | 917 info->weak_prerender_handle.get(); |
| 936 if (!existing_prerender_handle || !existing_prerender_handle->IsValid()) | 918 if (!existing_prerender_handle) |
| 937 continue; | 919 continue; |
| 938 | 920 |
| 939 DCHECK(existing_prerender_handle->IsPending()); | 921 DCHECK(!existing_prerender_handle->IsPrerendering()); |
| 940 DCHECK(process_id == -1 || session_storage_namespace); | 922 DCHECK(process_id == -1 || session_storage_namespace); |
| 941 | 923 |
| 942 scoped_ptr<PrerenderHandle> swap_prerender_handle(AddPrerender( | 924 scoped_ptr<PrerenderHandle> new_prerender_handle(AddPrerender( |
| 943 info->origin, process_id, | 925 info->origin, process_id, |
| 944 info->url, info->referrer, info->size, | 926 info->url, info->referrer, info->size, |
| 945 session_storage_namespace)); | 927 session_storage_namespace)); |
| 946 if (swap_prerender_handle.get()) { | 928 if (new_prerender_handle) { |
| 947 // AddPrerender has returned a new prerender handle to us. We want to make | 929 // AddPrerender has returned a new prerender handle to us. We want to make |
| 948 // |existing_prerender_handle| active, so swap the underlying | 930 // |existing_prerender_handle| active, so move the underlying |
| 949 // PrerenderData between the two handles, and delete our old handle (which | 931 // PrerenderData to our new handle. |
| 950 // will release our entry in the pending_prerender_list_). | 932 existing_prerender_handle->AdoptPrerenderDataFrom( |
| 951 existing_prerender_handle->SwapPrerenderDataWith( | 933 new_prerender_handle.get()); |
| 952 swap_prerender_handle.get()); | |
| 953 swap_prerender_handle->OnCancel(); | |
| 954 continue; | 934 continue; |
| 955 } | 935 } |
| 956 | |
| 957 // We could not start our Prerender. Canceling the existing handle will make | |
| 958 // it return false for PrerenderHandle::IsPending(), and will release the | |
| 959 // PrerenderData from pending_prerender_list_. | |
| 960 existing_prerender_handle->OnCancel(); | |
| 961 } | 936 } |
| 962 } | 937 } |
| 963 | 938 |
| 964 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { | 939 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { |
| 965 // The expiry time of our prerender data will likely change because of | 940 // The expiry time of our prerender data will likely change because of |
| 966 // this navigation. This requires a resort of active_prerenders_. | 941 // this navigation. This requires a resort of active_prerenders_. |
| 967 ScopedVector<PrerenderData>::iterator it = | 942 ScopedVector<PrerenderData>::iterator it = |
| 968 std::find(active_prerenders_.begin(), active_prerenders_.end(), | 943 std::find(active_prerenders_.begin(), active_prerenders_.end(), |
| 969 prerender_data); | 944 prerender_data); |
| 970 if (it == active_prerenders_.end()) | 945 if (it == active_prerenders_.end()) |
| 971 return; | 946 return; |
| 972 | 947 |
| 973 (*it)->set_expiry_time( | 948 (*it)->set_expiry_time( |
| 974 std::min((*it)->expiry_time(), | 949 std::min((*it)->expiry_time(), |
| 975 GetExpiryTimeForNavigatedAwayPrerender())); | 950 GetExpiryTimeForNavigatedAwayPrerender())); |
| 976 SortActivePrerenders(); | 951 SortActivePrerenders(); |
| 977 } | 952 } |
| 978 | 953 |
| 979 void PrerenderManager::DestroyPendingPrerenderData( | |
| 980 PrerenderData* pending_prerender_data) { | |
| 981 ScopedVector<PrerenderData>::iterator it = | |
| 982 std::find(pending_prerenders_.begin(), pending_prerenders_.end(), | |
| 983 pending_prerender_data); | |
| 984 if (it == pending_prerenders_.end()) | |
| 985 return; | |
| 986 pending_prerenders_.erase(it); | |
| 987 } | |
| 988 | |
| 989 // private | 954 // private |
| 990 PrerenderHandle* PrerenderManager::AddPrerender( | 955 PrerenderHandle* PrerenderManager::AddPrerender( |
| 991 Origin origin, | 956 Origin origin, |
| 992 int process_id, | 957 int process_id, |
| 993 const GURL& url_arg, | 958 const GURL& url_arg, |
| 994 const content::Referrer& referrer, | 959 const content::Referrer& referrer, |
| 995 const gfx::Size& size, | 960 const gfx::Size& size, |
| 996 SessionStorageNamespace* session_storage_namespace) { | 961 SessionStorageNamespace* session_storage_namespace) { |
| 997 DCHECK(CalledOnValidThread()); | 962 DCHECK(CalledOnValidThread()); |
| 998 | 963 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 if (!render_process_host || !render_process_host->GetBrowserContext()) | 1316 if (!render_process_host || !render_process_host->GetBrowserContext()) |
| 1352 return NULL; | 1317 return NULL; |
| 1353 Profile* profile = Profile::FromBrowserContext( | 1318 Profile* profile = Profile::FromBrowserContext( |
| 1354 render_process_host->GetBrowserContext()); | 1319 render_process_host->GetBrowserContext()); |
| 1355 if (!profile) | 1320 if (!profile) |
| 1356 return NULL; | 1321 return NULL; |
| 1357 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); | 1322 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); |
| 1358 } | 1323 } |
| 1359 | 1324 |
| 1360 } // namespace prerender | 1325 } // namespace prerender |
| OLD | NEW |