Chromium Code Reviews| 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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( | |
| 100 Origin origin, | |
| 101 const GURL& url, | |
| 102 const content::Referrer& referrer) | |
| 103 : origin(origin), | |
| 104 url(url), | |
| 105 referrer(referrer) { | |
| 106 } | |
| 107 | |
| 108 // TabContentsDelegateImpl ----------------------------------------------------- | 99 // TabContentsDelegateImpl ----------------------------------------------------- |
| 109 | 100 |
| 110 class PrerenderContents::TabContentsDelegateImpl | 101 class PrerenderContents::TabContentsDelegateImpl |
| 111 : public content::WebContentsDelegate { | 102 : public content::WebContentsDelegate { |
| 112 public: | 103 public: |
| 113 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : | 104 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : |
| 114 prerender_contents_(prerender_contents) { | 105 prerender_contents_(prerender_contents) { |
| 115 } | 106 } |
| 116 | 107 |
| 117 virtual WebContents* OpenURLFromTab(WebContents* source, | 108 virtual WebContents* OpenURLFromTab(WebContents* source, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 private: | 181 private: |
| 191 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > | 182 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > |
| 192 AddPageVector; | 183 AddPageVector; |
| 193 | 184 |
| 194 // Caches pages to be added to the history. | 185 // Caches pages to be added to the history. |
| 195 AddPageVector add_page_vector_; | 186 AddPageVector add_page_vector_; |
| 196 | 187 |
| 197 PrerenderContents* prerender_contents_; | 188 PrerenderContents* prerender_contents_; |
| 198 }; | 189 }; |
| 199 | 190 |
| 200 void PrerenderContents::AddPendingPrerender(Origin origin, | 191 void PrerenderContents::AddPendingPrerender(const GURL& url, |
| 201 const GURL& url, | |
| 202 const content::Referrer& referrer) { | 192 const content::Referrer& referrer) { |
| 203 pending_prerender_list_.push_back( | 193 pending_prerender_list_.push_back(PendingPrerenderData(url, referrer)); |
| 204 PendingPrerenderData(origin, url, referrer)); | |
| 205 } | 194 } |
| 206 | 195 |
| 207 bool PrerenderContents::IsPendingEntry(const GURL& url) const { | 196 bool PrerenderContents::IsPendingEntry(const GURL& url) const { |
| 208 for (PendingPrerenderList::const_iterator it = | 197 for (PendingPrerenderList::const_iterator it = |
| 209 pending_prerender_list_.begin(); | 198 pending_prerender_list_.begin(); |
| 210 it != pending_prerender_list_.end(); | 199 it != pending_prerender_list_.end(); |
| 211 ++it) { | 200 ++it) { |
| 212 if (it->url == url) | 201 if (it->first == url) |
| 213 return true; | 202 return true; |
| 214 } | 203 } |
| 215 return false; | 204 return false; |
| 216 } | 205 } |
| 217 | 206 |
| 218 void PrerenderContents::StartPendingPrerenders() { | 207 void PrerenderContents::StartPendingPrerenders() { |
| 219 PendingPrerenderList pending_prerender_list; | 208 PendingPrerenderList pending_prerender_list; |
| 220 pending_prerender_list.swap(pending_prerender_list_); | 209 pending_prerender_list.swap(pending_prerender_list_); |
| 221 for (PendingPrerenderList::iterator it = pending_prerender_list.begin(); | 210 for (PendingPrerenderList::iterator it = pending_prerender_list.begin(); |
| 222 it != pending_prerender_list.end(); | 211 it != pending_prerender_list.end(); |
| 223 ++it) { | 212 ++it) { |
| 224 prerender_manager_->AddPrerender(it->origin, | 213 RenderViewHost* render_view_host = RenderViewHost::FromID(child_id_, |
| 225 std::make_pair(child_id_, route_id_), | 214 route_id_); |
| 226 it->url, | 215 prerender_manager_->AddPrerenderFromLinkRelPrerender( |
| 227 it->referrer, | 216 child_id_, route_id_, it->first, it->second, size_, |
| 228 NULL); | 217 render_view_host->GetSessionStorageNamespace()); |
|
dominich
2012/04/30 15:52:05
I just noticed this fix. Thank you!
| |
| 229 } | 218 } |
| 230 } | 219 } |
| 231 | 220 |
| 232 PrerenderContents::PrerenderContents( | 221 PrerenderContents::PrerenderContents( |
| 233 PrerenderManager* prerender_manager, | 222 PrerenderManager* prerender_manager, |
| 234 PrerenderTracker* prerender_tracker, | 223 PrerenderTracker* prerender_tracker, |
| 235 Profile* profile, | 224 Profile* profile, |
| 236 const GURL& url, | 225 const GURL& url, |
| 237 const content::Referrer& referrer, | 226 const content::Referrer& referrer, |
| 238 Origin origin, | 227 Origin origin, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 260 bool PrerenderContents::Init() { | 249 bool PrerenderContents::Init() { |
| 261 return AddAliasURL(prerender_url_); | 250 return AddAliasURL(prerender_url_); |
| 262 } | 251 } |
| 263 | 252 |
| 264 // static | 253 // static |
| 265 PrerenderContents::Factory* PrerenderContents::CreateFactory() { | 254 PrerenderContents::Factory* PrerenderContents::CreateFactory() { |
| 266 return new PrerenderContentsFactoryImpl(); | 255 return new PrerenderContentsFactoryImpl(); |
| 267 } | 256 } |
| 268 | 257 |
| 269 void PrerenderContents::StartPrerendering( | 258 void PrerenderContents::StartPrerendering( |
| 270 const RenderViewHost* source_render_view_host, | 259 int creator_child_id, |
| 260 const gfx::Size& size, | |
| 271 content::SessionStorageNamespace* session_storage_namespace) { | 261 content::SessionStorageNamespace* session_storage_namespace) { |
| 272 DCHECK(profile_ != NULL); | 262 DCHECK(profile_ != NULL); |
| 273 DCHECK(!prerendering_has_started_); | 263 DCHECK(!prerendering_has_started_); |
| 274 DCHECK(prerender_contents_.get() == NULL); | 264 DCHECK(prerender_contents_.get() == NULL); |
| 265 DCHECK_EQ(-1, creator_child_id_); | |
| 266 DCHECK(size_.IsEmpty()); | |
| 267 | |
| 268 creator_child_id_ = creator_child_id; | |
| 269 size_ = size; | |
| 275 | 270 |
| 276 prerendering_has_started_ = true; | 271 prerendering_has_started_ = true; |
| 277 DCHECK(creator_child_id_ == -1); | 272 DCHECK_EQ(1U, alias_urls_.size()); |
| 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, | 273 InformRenderProcessAboutPrerender(prerender_url_, true, |
| 282 creator_child_id_); | 274 creator_child_id_); |
| 283 | 275 |
| 284 WebContents* new_contents = CreateWebContents(session_storage_namespace); | 276 WebContents* new_contents = CreateWebContents(session_storage_namespace); |
| 285 prerender_contents_.reset(new TabContentsWrapper(new_contents)); | 277 prerender_contents_.reset(new TabContentsWrapper(new_contents)); |
| 286 content::WebContentsObserver::Observe(new_contents); | 278 content::WebContentsObserver::Observe(new_contents); |
| 287 | 279 |
| 288 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds; | 280 if (size_.IsEmpty()) { |
| 289 if (source_render_view_host) { | 281 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) | 282 #if !defined(OS_ANDROID) |
| 299 // Try to get the active tab of the active browser and use that for tab | 283 // 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 | 284 // 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. | 285 // but we shouldn't be prerendering in that case anyway. |
| 302 // | 286 // |
| 303 // This code is unneeded on Android as we do not have a Browser object so we | 287 // 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 | 288 // can't get the size, and |default_tab_bounds| will be set to the right |
| 305 // value. | 289 // value. |
| 306 Browser* active_browser = BrowserList::GetLastActiveWithProfile(profile_); | 290 if (Browser* active_browser = |
| 307 if (active_browser) { | 291 BrowserList::GetLastActiveWithProfile(profile_)) { |
| 308 WebContents* active_web_contents = active_browser->GetWebContentsAt( | 292 WebContents* active_web_contents = active_browser->GetWebContentsAt( |
| 309 active_browser->active_index()); | 293 active_browser->active_index()); |
| 294 gfx::Rect container_bounds; | |
| 310 if (active_web_contents) | 295 if (active_web_contents) |
| 311 active_web_contents->GetView()->GetContainerBounds(&tab_bounds); | 296 active_web_contents->GetView()->GetContainerBounds(&container_bounds); |
| 297 size_ = container_bounds.size(); | |
| 312 } | 298 } |
| 313 #endif // !defined(OS_ANDROID) | 299 #endif // !defined(OS_ANDROID) |
| 314 } | 300 } |
| 315 | 301 |
| 316 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); | 302 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); |
| 317 new_contents->SetDelegate(tab_contents_delegate_.get()); | 303 new_contents->SetDelegate(tab_contents_delegate_.get()); |
| 318 | 304 |
| 319 // Set the size of the prerender WebContents. | 305 // Set the size of the prerender WebContents. |
| 320 prerender_contents_->web_contents()->GetView()->SizeContents( | 306 prerender_contents_->web_contents()->GetView()->SizeContents(size_); |
| 321 tab_bounds.size()); | |
| 322 | 307 |
| 323 // Register as an observer of the RenderViewHost so we get messages. | 308 // Register as an observer of the RenderViewHost so we get messages. |
| 324 render_view_host_observer_.reset( | 309 render_view_host_observer_.reset( |
| 325 new PrerenderRenderViewHostObserver(this, render_view_host_mutable())); | 310 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); |
| 326 | 311 |
| 327 child_id_ = render_view_host()->GetProcess()->GetID(); | 312 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); |
| 328 route_id_ = render_view_host()->GetRoutingID(); | 313 route_id_ = GetRenderViewHost()->GetRoutingID(); |
| 329 | 314 |
| 330 // Register this with the ResourceDispatcherHost as a prerender | 315 // Register this with the ResourceDispatcherHost as a prerender |
| 331 // RenderViewHost. This must be done before the Navigate message to catch all | 316 // RenderViewHost. This must be done before the Navigate message to catch all |
| 332 // resource requests, but as it is on the same thread as the Navigate message | 317 // resource requests, but as it is on the same thread as the Navigate message |
| 333 // (IO) there is no race condition. | 318 // (IO) there is no race condition. |
| 334 prerender_tracker_->OnPrerenderingStarted( | 319 prerender_tracker_->OnPrerenderingStarted( |
| 335 child_id_, | 320 child_id_, |
| 336 route_id_, | 321 route_id_, |
| 337 prerender_manager_); | 322 prerender_manager_); |
| 338 | 323 |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 // We may destroy the PrerenderContents before we have initialized the | 612 // We may destroy the PrerenderContents before we have initialized the |
| 628 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to | 613 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to |
| 629 // avoid any more messages being sent. | 614 // avoid any more messages being sent. |
| 630 if (render_view_host_observer_.get()) | 615 if (render_view_host_observer_.get()) |
| 631 render_view_host_observer_->set_prerender_contents(NULL); | 616 render_view_host_observer_->set_prerender_contents(NULL); |
| 632 } | 617 } |
| 633 | 618 |
| 634 base::ProcessMetrics* PrerenderContents::MaybeGetProcessMetrics() { | 619 base::ProcessMetrics* PrerenderContents::MaybeGetProcessMetrics() { |
| 635 if (process_metrics_.get() == NULL) { | 620 if (process_metrics_.get() == NULL) { |
| 636 // If a PrenderContents hasn't started prerending, don't be fully formed. | 621 // If a PrenderContents hasn't started prerending, don't be fully formed. |
| 637 if (!render_view_host() || !render_view_host()->GetProcess()) | 622 if (!GetRenderViewHost() || !GetRenderViewHost()->GetProcess()) |
| 638 return NULL; | 623 return NULL; |
| 639 base::ProcessHandle handle = render_view_host()->GetProcess()->GetHandle(); | 624 base::ProcessHandle handle = GetRenderViewHost()->GetProcess()->GetHandle(); |
| 640 if (handle == base::kNullProcessHandle) | 625 if (handle == base::kNullProcessHandle) |
| 641 return NULL; | 626 return NULL; |
| 642 #if !defined(OS_MACOSX) | 627 #if !defined(OS_MACOSX) |
| 643 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); | 628 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); |
| 644 #else | 629 #else |
| 645 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics( | 630 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics( |
| 646 handle, | 631 handle, |
| 647 content::BrowserChildProcessHost::GetPortProvider())); | 632 content::BrowserChildProcessHost::GetPortProvider())); |
| 648 #endif | 633 #endif |
| 649 } | 634 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 669 content::WebContentsObserver::Observe(NULL); | 654 content::WebContentsObserver::Observe(NULL); |
| 670 return prerender_contents_.release(); | 655 return prerender_contents_.release(); |
| 671 } | 656 } |
| 672 | 657 |
| 673 WebContents* PrerenderContents::GetWebContents() { | 658 WebContents* PrerenderContents::GetWebContents() { |
| 674 if (!prerender_contents_.get()) | 659 if (!prerender_contents_.get()) |
| 675 return NULL; | 660 return NULL; |
| 676 return prerender_contents_->web_contents(); | 661 return prerender_contents_->web_contents(); |
| 677 } | 662 } |
| 678 | 663 |
| 679 RenderViewHost* PrerenderContents::render_view_host_mutable() { | 664 RenderViewHost* PrerenderContents::GetRenderViewHostMutable() { |
| 680 return const_cast<RenderViewHost*>(render_view_host()); | 665 return const_cast<RenderViewHost*>(GetRenderViewHost()); |
| 681 } | 666 } |
| 682 | 667 |
| 683 const RenderViewHost* PrerenderContents::render_view_host() const { | 668 const RenderViewHost* PrerenderContents::GetRenderViewHost() const { |
| 684 if (!prerender_contents_.get()) | 669 if (!prerender_contents_.get()) |
| 685 return NULL; | 670 return NULL; |
| 686 return prerender_contents_->web_contents()->GetRenderViewHost(); | 671 return prerender_contents_->web_contents()->GetRenderViewHost(); |
| 687 } | 672 } |
| 688 | 673 |
| 689 void PrerenderContents::CommitHistory(TabContentsWrapper* tab) { | 674 void PrerenderContents::CommitHistory(TabContentsWrapper* tab) { |
| 690 if (tab_contents_delegate_.get()) | 675 if (tab_contents_delegate_.get()) |
| 691 tab_contents_delegate_->CommitHistory(tab); | 676 tab_contents_delegate_->CommitHistory(tab); |
| 692 } | 677 } |
| 693 | 678 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 705 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 690 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
| 706 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 691 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) |
| 707 return false; | 692 return false; |
| 708 const WebContents* web_contents = prerender_contents_->web_contents(); | 693 const WebContents* web_contents = prerender_contents_->web_contents(); |
| 709 return (web_contents->GetSiteInstance() != | 694 return (web_contents->GetSiteInstance() != |
| 710 web_contents->GetPendingSiteInstance()); | 695 web_contents->GetPendingSiteInstance()); |
| 711 } | 696 } |
| 712 | 697 |
| 713 | 698 |
| 714 } // namespace prerender | 699 } // namespace prerender |
| OLD | NEW |