| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #include "content/public/browser/notification_source.h" | 48 #include "content/public/browser/notification_source.h" |
| 49 #include "content/public/browser/render_process_host.h" | 49 #include "content/public/browser/render_process_host.h" |
| 50 #include "content/public/browser/render_view_host.h" | 50 #include "content/public/browser/render_view_host.h" |
| 51 #include "content/public/browser/session_storage_namespace.h" | 51 #include "content/public/browser/session_storage_namespace.h" |
| 52 #include "content/public/browser/web_contents.h" | 52 #include "content/public/browser/web_contents.h" |
| 53 #include "content/public/browser/web_contents_delegate.h" | 53 #include "content/public/browser/web_contents_delegate.h" |
| 54 #include "content/public/browser/web_contents_view.h" | 54 #include "content/public/browser/web_contents_view.h" |
| 55 | 55 |
| 56 using content::BrowserThread; | 56 using content::BrowserThread; |
| 57 using content::RenderViewHost; | 57 using content::RenderViewHost; |
| 58 using content::SessionStorageNamespace; | 58 using content::SessionStorageNamespaceMap; |
| 59 using content::WebContents; | 59 using content::WebContents; |
| 60 | 60 |
| 61 namespace prerender { | 61 namespace prerender { |
| 62 | 62 |
| 63 namespace { | 63 namespace { |
| 64 | 64 |
| 65 // Time interval at which periodic cleanups are performed. | 65 // Time interval at which periodic cleanups are performed. |
| 66 const int kPeriodicCleanupIntervalMs = 1000; | 66 const int kPeriodicCleanupIntervalMs = 1000; |
| 67 | 67 |
| 68 // Valid HTTP methods for prerendering. | 68 // Valid HTTP methods for prerendering. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 201 |
| 202 PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender( | 202 PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender( |
| 203 int process_id, | 203 int process_id, |
| 204 int route_id, | 204 int route_id, |
| 205 const GURL& url, | 205 const GURL& url, |
| 206 const content::Referrer& referrer, | 206 const content::Referrer& referrer, |
| 207 const gfx::Size& size) { | 207 const gfx::Size& size) { |
| 208 #if defined(OS_ANDROID) | 208 #if defined(OS_ANDROID) |
| 209 // TODO(jcivelli): http://crbug.com/113322 We should have an option to disable | 209 // TODO(jcivelli): http://crbug.com/113322 We should have an option to disable |
| 210 // link-prerender and enable omnibox-prerender only. | 210 // link-prerender and enable omnibox-prerender only. |
| 211 return NULL; | 211 return false; |
| 212 #else | 212 #else |
| 213 DCHECK(!size.IsEmpty()); | 213 DCHECK(!size.IsEmpty()); |
| 214 if (PrerenderData* parent_prerender_data = | 214 if (PrerenderData* parent_prerender_data = |
| 215 FindPrerenderDataForChildAndRoute(process_id, route_id)) { | 215 FindPrerenderDataForChildAndRoute(process_id, route_id)) { |
| 216 // Instead of prerendering from inside of a running prerender, we will defer | 216 // Instead of prerendering from inside of a running prerender, we will defer |
| 217 // this request until its launcher is made visible. | 217 // this request until its launcher is made visible. |
| 218 if (PrerenderContents* contents = parent_prerender_data->contents_) { | 218 if (PrerenderContents* contents = parent_prerender_data->contents_) { |
| 219 pending_prerender_list_.push_back( | 219 pending_prerender_list_.push_back( |
| 220 linked_ptr<PrerenderData>(new PrerenderData(this))); | 220 linked_ptr<PrerenderData>(new PrerenderData(this))); |
| 221 PrerenderHandle* prerender_handle = | 221 PrerenderHandle* prerender_handle = |
| 222 new PrerenderHandle(pending_prerender_list_.back().get()); | 222 new PrerenderHandle(pending_prerender_list_.back().get()); |
| 223 contents->AddPendingPrerender( | 223 contents->AddPendingPrerender( |
| 224 prerender_handle->weak_ptr_factory_.GetWeakPtr(), | 224 prerender_handle->weak_ptr_factory_.GetWeakPtr(), |
| 225 url, referrer, size); | 225 url, referrer, size); |
| 226 return prerender_handle; | 226 return prerender_handle; |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Unit tests pass in a process_id == -1. | 230 // Unit tests pass in a process_id == -1. |
| 231 SessionStorageNamespace* session_storage_namespace = NULL; | 231 if (process_id == -1) { |
| 232 if (process_id != -1) { | 232 return AddPrerender(ORIGIN_LINK_REL_PRERENDER, |
| 233 RenderViewHost* source_render_view_host = | 233 process_id, url, referrer, size, |
| 234 RenderViewHost::FromID(process_id, route_id); | 234 SessionStorageNamespaceMap()); |
| 235 if (!source_render_view_host) | |
| 236 return NULL; | |
| 237 WebContents* source_web_contents = | |
| 238 WebContents::FromRenderViewHost(source_render_view_host); | |
| 239 if (!source_web_contents) | |
| 240 return NULL; | |
| 241 // TODO(ajwong): This does not correctly handle storage for isolated apps. | |
| 242 session_storage_namespace = | |
| 243 source_web_contents->GetController() | |
| 244 .GetSessionStorageNamespaceMap().find("")->second; | |
| 245 } | 235 } |
| 246 | 236 |
| 237 RenderViewHost* source_render_view_host = |
| 238 RenderViewHost::FromID(process_id, route_id); |
| 239 if (!source_render_view_host) |
| 240 return NULL; |
| 241 |
| 242 WebContents* source_web_contents = |
| 243 WebContents::FromRenderViewHost(source_render_view_host); |
| 247 return AddPrerender(ORIGIN_LINK_REL_PRERENDER, | 244 return AddPrerender(ORIGIN_LINK_REL_PRERENDER, |
| 248 process_id, url, referrer, size, | 245 process_id, url, referrer, size, |
| 249 session_storage_namespace); | 246 source_web_contents->GetController() |
| 247 .GetSessionStorageNamespaceMap()); |
| 250 #endif | 248 #endif |
| 251 } | 249 } |
| 252 | 250 |
| 253 PrerenderHandle* PrerenderManager::AddPrerenderFromOmnibox( | 251 PrerenderHandle* PrerenderManager::AddPrerenderFromOmnibox( |
| 254 const GURL& url, | 252 const GURL& url, |
| 255 SessionStorageNamespace* session_storage_namespace, | 253 const SessionStorageNamespaceMap& session_storage_namespace_map, |
| 256 const gfx::Size& size) { | 254 const gfx::Size& size) { |
| 257 if (!IsOmniboxEnabled(profile_)) | 255 if (!IsOmniboxEnabled(profile_)) |
| 258 return NULL; | 256 return NULL; |
| 259 return AddPrerender(ORIGIN_OMNIBOX, -1, url, content::Referrer(), size, | 257 return AddPrerender(ORIGIN_OMNIBOX, -1, url, content::Referrer(), size, |
| 260 session_storage_namespace); | 258 session_storage_namespace_map); |
| 261 } | 259 } |
| 262 | 260 |
| 263 void PrerenderManager::DestroyPrerenderForRenderView( | 261 void PrerenderManager::DestroyPrerenderForRenderView( |
| 264 int process_id, int view_id, FinalStatus final_status) { | 262 int process_id, int view_id, FinalStatus final_status) { |
| 265 DCHECK(CalledOnValidThread()); | 263 DCHECK(CalledOnValidThread()); |
| 266 if (PrerenderData* prerender_data = | 264 if (PrerenderData* prerender_data = |
| 267 FindPrerenderDataForChildAndRoute(process_id, view_id)) { | 265 FindPrerenderDataForChildAndRoute(process_id, view_id)) { |
| 268 prerender_data->contents_->Destroy(final_status); | 266 prerender_data->contents_->Destroy(final_status); |
| 269 } | 267 } |
| 270 } | 268 } |
| 271 | 269 |
| 272 void PrerenderManager::CancelAllPrerenders() { | 270 void PrerenderManager::CancelAllPrerenders() { |
| 273 DCHECK(CalledOnValidThread()); | 271 DCHECK(CalledOnValidThread()); |
| 274 while (!active_prerender_list_.empty()) { | 272 while (!active_prerender_list_.empty()) { |
| 275 PrerenderContents* prerender_contents = | 273 PrerenderContents* prerender_contents = |
| 276 active_prerender_list_.front()->contents(); | 274 active_prerender_list_.front()->contents(); |
| 277 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); | 275 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); |
| 278 } | 276 } |
| 279 } | 277 } |
| 280 | 278 |
| 281 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, | 279 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, |
| 282 const GURL& url) { | 280 const GURL& url) { |
| 283 DCHECK(CalledOnValidThread()); | 281 DCHECK(CalledOnValidThread()); |
| 284 DCHECK(!IsWebContentsPrerendering(web_contents)); | 282 DCHECK(!IsWebContentsPrerendering(web_contents)); |
| 285 | 283 |
| 284 const SessionStorageNamespaceMap& old_session_storage_namespace_map = |
| 285 web_contents->GetController().GetSessionStorageNamespaceMap(); |
| 286 DeleteOldEntries(); | 286 DeleteOldEntries(); |
| 287 DeletePendingDeleteEntries(); | 287 DeletePendingDeleteEntries(); |
| 288 // TODO(ajwong): This doesn't handle isolated apps correctly. | 288 PrerenderData* prerender_data = |
| 289 PrerenderData* prerender_data = FindPrerenderData( | 289 FindPrerenderData(url, old_session_storage_namespace_map); |
| 290 url, | |
| 291 web_contents->GetController().GetSessionStorageNamespaceMap() | |
| 292 .find("")->second); | |
| 293 if (!prerender_data) | 290 if (!prerender_data) |
| 294 return false; | 291 return false; |
| 295 DCHECK(prerender_data->contents_); | 292 DCHECK(prerender_data->contents_); |
| 296 if (IsNoSwapInExperiment(prerender_data->contents_->experiment_id())) | 293 if (IsNoSwapInExperiment(prerender_data->contents_->experiment_id())) |
| 297 return false; | 294 return false; |
| 298 | 295 |
| 299 if (TabContents* new_tab_contents = | 296 if (TabContents* new_tab_contents = |
| 300 prerender_data->contents_->prerender_contents()) { | 297 prerender_data->contents_->prerender_contents()) { |
| 301 if (web_contents == new_tab_contents->web_contents()) | 298 if (web_contents == new_tab_contents->web_contents()) |
| 302 return false; // Do not swap in to ourself. | 299 return false; // Do not swap in to ourself. |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 prerender_contents_factory_.reset(prerender_contents_factory); | 800 prerender_contents_factory_.reset(prerender_contents_factory); |
| 804 } | 801 } |
| 805 | 802 |
| 806 void PrerenderManager::StartPendingPrerender( | 803 void PrerenderManager::StartPendingPrerender( |
| 807 PrerenderHandle* existing_prerender_handle, | 804 PrerenderHandle* existing_prerender_handle, |
| 808 Origin origin, | 805 Origin origin, |
| 809 int process_id, | 806 int process_id, |
| 810 const GURL& url, | 807 const GURL& url, |
| 811 const content::Referrer& referrer, | 808 const content::Referrer& referrer, |
| 812 const gfx::Size& size, | 809 const gfx::Size& size, |
| 813 content::SessionStorageNamespace* session_storage_namespace) { | 810 const content::SessionStorageNamespaceMap& session_storage_namespace_map) { |
| 814 DCHECK(existing_prerender_handle); | 811 DCHECK(existing_prerender_handle); |
| 815 DCHECK(existing_prerender_handle->IsValid()); | 812 DCHECK(existing_prerender_handle->IsValid()); |
| 816 DCHECK(existing_prerender_handle->IsPending()); | 813 DCHECK(existing_prerender_handle->IsPending()); |
| 817 | 814 |
| 818 DVLOG(6) << "StartPendingPrerender"; | 815 DVLOG(6) << "StartPendingPrerender"; |
| 819 DVLOG(6) << "existing_prerender_handle->handle_count_ = " << | 816 DVLOG(6) << "existing_prerender_handle->handle_count_ = " << |
| 820 existing_prerender_handle->prerender_data_->handle_count_; | 817 existing_prerender_handle->prerender_data_->handle_count_; |
| 821 | 818 |
| 822 DCHECK(process_id == -1 || session_storage_namespace); | 819 DCHECK(process_id == -1 || !session_storage_namespace_map.empty()); |
| 823 | 820 |
| 824 scoped_ptr<PrerenderHandle> swap_prerender_handle(AddPrerender( | 821 scoped_ptr<PrerenderHandle> swap_prerender_handle(AddPrerender( |
| 825 origin, process_id, url, referrer, size, session_storage_namespace)); | 822 origin, process_id, url, referrer, size, session_storage_namespace_map)); |
| 826 if (swap_prerender_handle.get()) { | 823 if (swap_prerender_handle.get()) { |
| 827 // AddPrerender has returned a new prerender handle to us. We want to make | 824 // AddPrerender has returned a new prerender handle to us. We want to make |
| 828 // |existing_prerender_handle| active, so swap the underlying PrerenderData | 825 // |existing_prerender_handle| active, so swap the underlying PrerenderData |
| 829 // between the two handles, and delete our old handle (which will release | 826 // between the two handles, and delete our old handle (which will release |
| 830 // our entry in the pending_prerender_list_). | 827 // our entry in the pending_prerender_list_). |
| 831 existing_prerender_handle->SwapPrerenderDataWith( | 828 existing_prerender_handle->SwapPrerenderDataWith( |
| 832 swap_prerender_handle.get()); | 829 swap_prerender_handle.get()); |
| 833 swap_prerender_handle->OnCancel(); | 830 swap_prerender_handle->OnCancel(); |
| 834 return; | 831 return; |
| 835 } | 832 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 864 DCHECK(active_prerender_list_.empty()); | 861 DCHECK(active_prerender_list_.empty()); |
| 865 } | 862 } |
| 866 | 863 |
| 867 // private | 864 // private |
| 868 PrerenderHandle* PrerenderManager::AddPrerender( | 865 PrerenderHandle* PrerenderManager::AddPrerender( |
| 869 Origin origin, | 866 Origin origin, |
| 870 int process_id, | 867 int process_id, |
| 871 const GURL& url_arg, | 868 const GURL& url_arg, |
| 872 const content::Referrer& referrer, | 869 const content::Referrer& referrer, |
| 873 const gfx::Size& size, | 870 const gfx::Size& size, |
| 874 SessionStorageNamespace* session_storage_namespace) { | 871 const SessionStorageNamespaceMap& session_storage_namespace_map) { |
| 875 DCHECK(CalledOnValidThread()); | 872 DCHECK(CalledOnValidThread()); |
| 876 | 873 |
| 877 if (!IsEnabled()) | 874 if (!IsEnabled()) |
| 878 return NULL; | 875 return NULL; |
| 879 | 876 |
| 880 if (origin == ORIGIN_LINK_REL_PRERENDER && | 877 if (origin == ORIGIN_LINK_REL_PRERENDER && |
| 881 IsGoogleSearchResultURL(referrer.url)) { | 878 IsGoogleSearchResultURL(referrer.url)) { |
| 882 origin = ORIGIN_GWS_PRERENDER; | 879 origin = ORIGIN_GWS_PRERENDER; |
| 883 } | 880 } |
| 884 | 881 |
| 885 DeleteOldEntries(); | 882 DeleteOldEntries(); |
| 886 DeletePendingDeleteEntries(); | 883 DeletePendingDeleteEntries(); |
| 887 | 884 |
| 888 GURL url = url_arg; | 885 GURL url = url_arg; |
| 889 GURL alias_url; | 886 GURL alias_url; |
| 890 uint8 experiment = GetQueryStringBasedExperiment(url_arg); | 887 uint8 experiment = GetQueryStringBasedExperiment(url_arg); |
| 891 bool control_group_behavior = | 888 bool control_group_behavior = |
| 892 IsControlGroup() || IsControlGroupExperiment(experiment); | 889 IsControlGroup() || IsControlGroupExperiment(experiment); |
| 893 if (control_group_behavior && | 890 if (control_group_behavior && |
| 894 MaybeGetQueryStringBasedAliasURL(url, &alias_url)) { | 891 MaybeGetQueryStringBasedAliasURL(url, &alias_url)) { |
| 895 url = alias_url; | 892 url = alias_url; |
| 896 } | 893 } |
| 897 | 894 |
| 898 // From here on, we will record a FinalStatus so we need to register with the | 895 // From here on, we will record a FinalStatus so we need to register with the |
| 899 // histogram tracking. | 896 // histogram tracking. |
| 900 histograms_->RecordPrerender(origin, url_arg); | 897 histograms_->RecordPrerender(origin, url_arg); |
| 901 | 898 |
| 902 if (PrerenderData* preexisting_prerender_data = | 899 if (PrerenderData* preexisting_prerender_data = |
| 903 FindPrerenderData(url, session_storage_namespace)) { | 900 FindPrerenderData(url, session_storage_namespace_map)) { |
| 904 RecordFinalStatus(origin, experiment, FINAL_STATUS_DUPLICATE); | 901 RecordFinalStatus(origin, experiment, FINAL_STATUS_DUPLICATE); |
| 905 return new PrerenderHandle(preexisting_prerender_data); | 902 return new PrerenderHandle(preexisting_prerender_data); |
| 906 } | 903 } |
| 907 | 904 |
| 908 // Do not prerender if there are too many render processes, and we would | 905 // Do not prerender if there are too many render processes, and we would |
| 909 // have to use an existing one. We do not want prerendering to happen in | 906 // have to use an existing one. We do not want prerendering to happen in |
| 910 // a shared process, so that we can always reliably lower the CPU | 907 // a shared process, so that we can always reliably lower the CPU |
| 911 // priority for prerendering. | 908 // priority for prerendering. |
| 912 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns | 909 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns |
| 913 // true, so that case needs to be explicitly checked for. | 910 // true, so that case needs to be explicitly checked for. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 linked_ptr<PrerenderData>(new PrerenderData(this, prerender_contents))); | 942 linked_ptr<PrerenderData>(new PrerenderData(this, prerender_contents))); |
| 946 PrerenderHandle* prerender_handle = | 943 PrerenderHandle* prerender_handle = |
| 947 new PrerenderHandle(active_prerender_list_.back().get()); | 944 new PrerenderHandle(active_prerender_list_.back().get()); |
| 948 | 945 |
| 949 last_prerender_start_time_ = GetCurrentTimeTicks(); | 946 last_prerender_start_time_ = GetCurrentTimeTicks(); |
| 950 | 947 |
| 951 gfx::Size contents_size = | 948 gfx::Size contents_size = |
| 952 size.IsEmpty() ? config_.default_tab_bounds.size() : size; | 949 size.IsEmpty() ? config_.default_tab_bounds.size() : size; |
| 953 | 950 |
| 954 prerender_contents->StartPrerendering(process_id, contents_size, | 951 prerender_contents->StartPrerendering(process_id, contents_size, |
| 955 session_storage_namespace, | 952 session_storage_namespace_map, |
| 956 control_group_behavior); | 953 control_group_behavior); |
| 957 | 954 |
| 958 while (active_prerender_list_.size() > config_.max_concurrency) { | 955 while (active_prerender_list_.size() > config_.max_concurrency) { |
| 959 prerender_contents = active_prerender_list_.front()->contents_; | 956 prerender_contents = active_prerender_list_.front()->contents_; |
| 960 DCHECK(prerender_contents); | 957 DCHECK(prerender_contents); |
| 961 prerender_contents->Destroy(FINAL_STATUS_EVICTED); | 958 prerender_contents->Destroy(FINAL_STATUS_EVICTED); |
| 962 } | 959 } |
| 963 | 960 |
| 964 histograms_->RecordConcurrency(active_prerender_list_.size()); | 961 histograms_->RecordConcurrency(active_prerender_list_.size()); |
| 965 | 962 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 void PrerenderManager::DeletePendingDeleteEntries() { | 1054 void PrerenderManager::DeletePendingDeleteEntries() { |
| 1058 while (!pending_delete_list_.empty()) { | 1055 while (!pending_delete_list_.empty()) { |
| 1059 PrerenderContents* contents = pending_delete_list_.front(); | 1056 PrerenderContents* contents = pending_delete_list_.front(); |
| 1060 pending_delete_list_.pop_front(); | 1057 pending_delete_list_.pop_front(); |
| 1061 delete contents; | 1058 delete contents; |
| 1062 } | 1059 } |
| 1063 } | 1060 } |
| 1064 | 1061 |
| 1065 PrerenderManager::PrerenderData* PrerenderManager::FindPrerenderData( | 1062 PrerenderManager::PrerenderData* PrerenderManager::FindPrerenderData( |
| 1066 const GURL& url, | 1063 const GURL& url, |
| 1067 const SessionStorageNamespace* session_storage_namespace) { | 1064 const SessionStorageNamespaceMap& session_storage_namespace_map) { |
| 1068 for (std::list<linked_ptr<PrerenderData> >::iterator | 1065 for (std::list<linked_ptr<PrerenderData> >::iterator |
| 1069 it = active_prerender_list_.begin(); | 1066 it = active_prerender_list_.begin(); |
| 1070 it != active_prerender_list_.end(); | 1067 it != active_prerender_list_.end(); |
| 1071 ++it) { | 1068 ++it) { |
| 1072 PrerenderContents* prerender_contents = it->get()->contents_; | 1069 PrerenderContents* prerender_contents = it->get()->contents_; |
| 1073 if (prerender_contents->Matches(url, session_storage_namespace)) | 1070 if (prerender_contents->Matches(url, session_storage_namespace_map)) |
| 1074 return it->get(); | 1071 return it->get(); |
| 1075 } | 1072 } |
| 1076 return NULL; | 1073 return NULL; |
| 1077 } | 1074 } |
| 1078 | 1075 |
| 1079 PrerenderManager::PrerenderData* | 1076 PrerenderManager::PrerenderData* |
| 1080 PrerenderManager::FindPrerenderDataForChildAndRoute( | 1077 PrerenderManager::FindPrerenderDataForChildAndRoute( |
| 1081 const int child_id, const int route_id) { | 1078 const int child_id, const int route_id) { |
| 1082 for (std::list<linked_ptr<PrerenderData> >::iterator | 1079 for (std::list<linked_ptr<PrerenderData> >::iterator |
| 1083 it = active_prerender_list_.begin(); | 1080 it = active_prerender_list_.begin(); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 if (!render_process_host || !render_process_host->GetBrowserContext()) | 1233 if (!render_process_host || !render_process_host->GetBrowserContext()) |
| 1237 return NULL; | 1234 return NULL; |
| 1238 Profile* profile = Profile::FromBrowserContext( | 1235 Profile* profile = Profile::FromBrowserContext( |
| 1239 render_process_host->GetBrowserContext()); | 1236 render_process_host->GetBrowserContext()); |
| 1240 if (!profile) | 1237 if (!profile) |
| 1241 return NULL; | 1238 return NULL; |
| 1242 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); | 1239 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); |
| 1243 } | 1240 } |
| 1244 | 1241 |
| 1245 } // namespace prerender | 1242 } // namespace prerender |
| OLD | NEW |