 Chromium Code Reviews
 Chromium Code Reviews Issue 10198040:
  New link rel=prerender api, using WebKit::WebPrerenderingPlatform  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 10198040:
  New link rel=prerender api, using WebKit::WebPrerenderingPlatform  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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_contents.h" | 5 #include "chrome/browser/prerender/prerender_contents.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <utility> | 8 #include <utility> | 
| 9 | 9 | 
| 10 #include "base/process_util.h" | 10 #include "base/process_util.h" | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 if (!render_process_host) | 76 if (!render_process_host) | 
| 77 return; | 77 return; | 
| 78 IPC::Message* message = NULL; | 78 IPC::Message* message = NULL; | 
| 79 if (is_add) | 79 if (is_add) | 
| 80 message = new PrerenderMsg_AddPrerenderURL(url); | 80 message = new PrerenderMsg_AddPrerenderURL(url); | 
| 81 else | 81 else | 
| 82 message = new PrerenderMsg_RemovePrerenderURL(url); | 82 message = new PrerenderMsg_RemovePrerenderURL(url); | 
| 83 render_process_host->Send(message); | 83 render_process_host->Send(message); | 
| 84 } | 84 } | 
| 85 | 85 | 
| 86 } // end namespace | 86 } // namespace | 
| 87 | 87 | 
| 88 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { | 88 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { | 
| 89 public: | 89 public: | 
| 90 virtual PrerenderContents* CreatePrerenderContents( | 90 virtual PrerenderContents* CreatePrerenderContents( | 
| 91 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, | 91 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, | 
| 92 Profile* profile, const GURL& url, const content::Referrer& referrer, | 92 Profile* profile, const GURL& url, const content::Referrer& referrer, | 
| 93 Origin origin, uint8 experiment_id) OVERRIDE { | 93 Origin origin, uint8 experiment_id) OVERRIDE { | 
| 94 return new PrerenderContents(prerender_manager, prerender_tracker, profile, | 94 return new PrerenderContents(prerender_manager, prerender_tracker, profile, | 
| 95 url, referrer, origin, experiment_id); | 95 url, referrer, origin, experiment_id); | 
| 96 } | 96 } | 
| 97 }; | 97 }; | 
| 98 | 98 | 
| 99 PrerenderContents::PendingPrerenderData::PendingPrerenderData( | 99 struct PrerenderContents::PendingPrerenderInfo { | 
| 100 Origin origin, | 100 PendingPrerenderInfo(const GURL& url, | 
| 101 const content::Referrer& referrer, | |
| 102 const gfx::Size& size); | |
| 103 const GURL url; | |
| 104 const content::Referrer referrer; | |
| 105 const gfx::Size size; | |
| 106 }; | |
| 107 | |
| 108 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( | |
| 101 const GURL& url, | 109 const GURL& url, | 
| 102 const content::Referrer& referrer) | 110 const content::Referrer& referrer, | 
| 103 : origin(origin), | 111 const gfx::Size& size) | 
| 104 url(url), | 112 : url(url), | 
| 105 referrer(referrer) { | 113 referrer(referrer), | 
| 114 size(size) { | |
| 106 } | 115 } | 
| 107 | 116 | 
| 108 // TabContentsDelegateImpl ----------------------------------------------------- | 117 // TabContentsDelegateImpl ----------------------------------------------------- | 
| 109 | 118 | 
| 110 class PrerenderContents::TabContentsDelegateImpl | 119 class PrerenderContents::TabContentsDelegateImpl | 
| 111 : public content::WebContentsDelegate { | 120 : public content::WebContentsDelegate { | 
| 112 public: | 121 public: | 
| 113 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : | 122 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : | 
| 114 prerender_contents_(prerender_contents) { | 123 prerender_contents_(prerender_contents) { | 
| 115 } | 124 } | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 private: | 199 private: | 
| 191 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > | 200 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > | 
| 192 AddPageVector; | 201 AddPageVector; | 
| 193 | 202 | 
| 194 // Caches pages to be added to the history. | 203 // Caches pages to be added to the history. | 
| 195 AddPageVector add_page_vector_; | 204 AddPageVector add_page_vector_; | 
| 196 | 205 | 
| 197 PrerenderContents* prerender_contents_; | 206 PrerenderContents* prerender_contents_; | 
| 198 }; | 207 }; | 
| 199 | 208 | 
| 200 void PrerenderContents::AddPendingPrerender(Origin origin, | 209 void PrerenderContents::AddPendingPrerender(const GURL& url, | 
| 201 const GURL& url, | 210 const content::Referrer& referrer, | 
| 202 const content::Referrer& referrer) { | 211 const gfx::Size& size) { | 
| 203 pending_prerender_list_.push_back( | 212 pending_prerender_list_.push_back(PendingPrerenderInfo(url, referrer, size)); | 
| 204 PendingPrerenderData(origin, url, referrer)); | |
| 205 } | 213 } | 
| 206 | 214 | 
| 207 bool PrerenderContents::IsPendingEntry(const GURL& url) const { | 215 bool PrerenderContents::IsPendingEntry(const GURL& url) const { | 
| 208 for (PendingPrerenderList::const_iterator it = | 216 for (PendingPrerenderList::const_iterator it = | 
| 209 pending_prerender_list_.begin(); | 217 pending_prerender_list_.begin(); | 
| 210 it != pending_prerender_list_.end(); | 218 it != pending_prerender_list_.end(); | 
| 211 ++it) { | 219 ++it) { | 
| 212 if (it->url == url) | 220 if (it->url == url) | 
| 213 return true; | 221 return true; | 
| 214 } | 222 } | 
| 215 return false; | 223 return false; | 
| 216 } | 224 } | 
| 217 | 225 | 
| 218 void PrerenderContents::StartPendingPrerenders() { | 226 void PrerenderContents::StartPendingPrerenders() { | 
| 219 PendingPrerenderList pending_prerender_list; | 227 PendingPrerenderList pending_prerender_list; | 
| 220 pending_prerender_list.swap(pending_prerender_list_); | 228 pending_prerender_list.swap(pending_prerender_list_); | 
| 221 for (PendingPrerenderList::iterator it = pending_prerender_list.begin(); | 229 for (PendingPrerenderList::iterator it = pending_prerender_list.begin(); | 
| 222 it != pending_prerender_list.end(); | 230 it != pending_prerender_list.end(); | 
| 223 ++it) { | 231 ++it) { | 
| 224 prerender_manager_->AddPrerender(it->origin, | 232 prerender_manager_->AddPrerenderFromLinkRelPrerender( | 
| 225 std::make_pair(child_id_, route_id_), | 233 child_id_, route_id_, it->url, it->referrer, it->size); | 
| 226 it->url, | |
| 227 it->referrer, | |
| 228 NULL); | |
| 229 } | 234 } | 
| 230 } | 235 } | 
| 231 | 236 | 
| 232 PrerenderContents::PrerenderContents( | 237 PrerenderContents::PrerenderContents( | 
| 233 PrerenderManager* prerender_manager, | 238 PrerenderManager* prerender_manager, | 
| 234 PrerenderTracker* prerender_tracker, | 239 PrerenderTracker* prerender_tracker, | 
| 235 Profile* profile, | 240 Profile* profile, | 
| 236 const GURL& url, | 241 const GURL& url, | 
| 237 const content::Referrer& referrer, | 242 const content::Referrer& referrer, | 
| 238 Origin origin, | 243 Origin origin, | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 260 bool PrerenderContents::Init() { | 265 bool PrerenderContents::Init() { | 
| 261 return AddAliasURL(prerender_url_); | 266 return AddAliasURL(prerender_url_); | 
| 262 } | 267 } | 
| 263 | 268 | 
| 264 // static | 269 // static | 
| 265 PrerenderContents::Factory* PrerenderContents::CreateFactory() { | 270 PrerenderContents::Factory* PrerenderContents::CreateFactory() { | 
| 266 return new PrerenderContentsFactoryImpl(); | 271 return new PrerenderContentsFactoryImpl(); | 
| 267 } | 272 } | 
| 268 | 273 | 
| 269 void PrerenderContents::StartPrerendering( | 274 void PrerenderContents::StartPrerendering( | 
| 270 const RenderViewHost* source_render_view_host, | 275 int creator_child_id, | 
| 276 const gfx::Size& size, | |
| 271 content::SessionStorageNamespace* session_storage_namespace) { | 277 content::SessionStorageNamespace* session_storage_namespace) { | 
| 272 DCHECK(profile_ != NULL); | 278 DCHECK(profile_ != NULL); | 
| 273 DCHECK(!prerendering_has_started_); | 279 DCHECK(!prerendering_has_started_); | 
| 274 DCHECK(prerender_contents_.get() == NULL); | 280 DCHECK(prerender_contents_.get() == NULL); | 
| 281 DCHECK_EQ(-1, creator_child_id_); | |
| 282 DCHECK(size_.IsEmpty()); | |
| 283 | |
| 284 creator_child_id_ = creator_child_id; | |
| 285 size_ = size; | |
| 275 | 286 | 
| 276 prerendering_has_started_ = true; | 287 prerendering_has_started_ = true; | 
| 277 DCHECK(creator_child_id_ == -1); | 288 DCHECK_EQ(1U, alias_urls_.size()); | 
| 
cbentzel
2012/05/04 15:32:25
Nit: may as well move these near all of the other
 
gavinp
2012/05/04 23:10:51
Done.
 | |
| 278 DCHECK(alias_urls_.size() == 1); | |
| 279 if (source_render_view_host) | |
| 280 creator_child_id_ = source_render_view_host->GetProcess()->GetID(); | |
| 281 InformRenderProcessAboutPrerender(prerender_url_, true, | 289 InformRenderProcessAboutPrerender(prerender_url_, true, | 
| 282 creator_child_id_); | 290 creator_child_id_); | 
| 283 | 291 | 
| 284 WebContents* new_contents = CreateWebContents(session_storage_namespace); | 292 WebContents* new_contents = CreateWebContents(session_storage_namespace); | 
| 285 prerender_contents_.reset(new TabContentsWrapper(new_contents)); | 293 prerender_contents_.reset(new TabContentsWrapper(new_contents)); | 
| 286 content::WebContentsObserver::Observe(new_contents); | 294 content::WebContentsObserver::Observe(new_contents); | 
| 287 | 295 | 
| 288 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds; | 296 if (size_.IsEmpty()) { | 
| 
cbentzel
2012/05/04 15:32:25
Nit: Should this be done closer to the size_ = siz
 
gavinp
2012/05/04 23:10:51
Done.
 | |
| 289 if (source_render_view_host) { | 297 size_ = prerender_manager_->config().default_tab_bounds.size(); | 
| 290 DCHECK(source_render_view_host->GetView() != NULL); | |
| 291 WebContents* source_wc = | |
| 292 source_render_view_host->GetDelegate()->GetAsWebContents(); | |
| 293 if (source_wc) { | |
| 294 // Set the size of the new TC to that of the old TC. | |
| 295 source_wc->GetView()->GetContainerBounds(&tab_bounds); | |
| 296 } | |
| 297 } else { | |
| 298 #if !defined(OS_ANDROID) | 298 #if !defined(OS_ANDROID) | 
| 299 // Try to get the active tab of the active browser and use that for tab | 299 // Try to get the active tab of the active browser and use that for tab | 
| 300 // bounds. If the browser has never been active, we will fail to get a size | 300 // bounds. If the browser has never been active, we will fail to get a size | 
| 301 // but we shouldn't be prerendering in that case anyway. | 301 // but we shouldn't be prerendering in that case anyway. | 
| 302 // | 302 // | 
| 303 // This code is unneeded on Android as we do not have a Browser object so we | 303 // This code is unneeded on Android as we do not have a Browser object so we | 
| 304 // can't get the size, and |default_tab_bounds| will be set to the right | 304 // can't get the size, and |default_tab_bounds| will be set to the right | 
| 305 // value. | 305 // value. | 
| 306 Browser* active_browser = BrowserList::GetLastActiveWithProfile(profile_); | 306 if (Browser* active_browser = | 
| 307 if (active_browser) { | 307 BrowserList::GetLastActiveWithProfile(profile_)) { | 
| 
cbentzel
2012/05/04 15:32:25
Nit: not sure what this buys other than slightly t
 
gavinp
2012/05/04 23:10:51
This practice is specifically recommended in our c
 | |
| 308 WebContents* active_web_contents = active_browser->GetWebContentsAt( | 308 WebContents* active_web_contents = active_browser->GetWebContentsAt( | 
| 309 active_browser->active_index()); | 309 active_browser->active_index()); | 
| 310 gfx::Rect container_bounds; | |
| 310 if (active_web_contents) | 311 if (active_web_contents) | 
| 311 active_web_contents->GetView()->GetContainerBounds(&tab_bounds); | 312 active_web_contents->GetView()->GetContainerBounds(&container_bounds); | 
| 313 size_ = container_bounds.size(); | |
| 
cbentzel
2012/05/04 15:32:25
IMPORTANT: This is a change in behavior from befor
 
gavinp
2012/05/04 23:10:51
Good catch.  Fixed.
 | |
| 312 } | 314 } | 
| 313 #endif // !defined(OS_ANDROID) | 315 #endif // !defined(OS_ANDROID) | 
| 314 } | 316 } | 
| 315 | 317 | 
| 316 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); | 318 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); | 
| 317 new_contents->SetDelegate(tab_contents_delegate_.get()); | 319 new_contents->SetDelegate(tab_contents_delegate_.get()); | 
| 318 | 320 | 
| 319 // Set the size of the prerender WebContents. | 321 // Set the size of the prerender WebContents. | 
| 320 prerender_contents_->web_contents()->GetView()->SizeContents( | 322 prerender_contents_->web_contents()->GetView()->SizeContents(size_); | 
| 321 tab_bounds.size()); | |
| 322 | 323 | 
| 323 // Register as an observer of the RenderViewHost so we get messages. | 324 // Register as an observer of the RenderViewHost so we get messages. | 
| 324 render_view_host_observer_.reset( | 325 render_view_host_observer_.reset( | 
| 325 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); | 326 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); | 
| 326 | 327 | 
| 327 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); | 328 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); | 
| 328 route_id_ = GetRenderViewHost()->GetRoutingID(); | 329 route_id_ = GetRenderViewHost()->GetRoutingID(); | 
| 329 | 330 | 
| 330 // Register this with the ResourceDispatcherHost as a prerender | 331 // Register this with the ResourceDispatcherHost as a prerender | 
| 331 // RenderViewHost. This must be done before the Navigate message to catch all | 332 // RenderViewHost. This must be done before the Navigate message to catch all | 
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 706 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 
| 706 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 707 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 
| 707 return false; | 708 return false; | 
| 708 const WebContents* web_contents = prerender_contents_->web_contents(); | 709 const WebContents* web_contents = prerender_contents_->web_contents(); | 
| 709 return (web_contents->GetSiteInstance() != | 710 return (web_contents->GetSiteInstance() != | 
| 710 web_contents->GetPendingSiteInstance()); | 711 web_contents->GetPendingSiteInstance()); | 
| 711 } | 712 } | 
| 712 | 713 | 
| 713 | 714 | 
| 714 } // namespace prerender | 715 } // namespace prerender | 
| OLD | NEW |