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

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

Issue 9416031: Prerendered pages are swapped in at browser::Navigate time. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Base files missing Created 8 years, 9 months 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_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"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/history/history_tab_helper.h" 12 #include "chrome/browser/history/history_tab_helper.h"
13 #include "chrome/browser/history/history_types.h" 13 #include "chrome/browser/history/history_types.h"
14 #include "chrome/browser/prerender/prerender_final_status.h" 14 #include "chrome/browser/prerender/prerender_final_status.h"
15 #include "chrome/browser/prerender/prerender_manager.h" 15 #include "chrome/browser/prerender/prerender_manager.h"
16 #include "chrome/browser/prerender/prerender_render_view_host_observer.h" 16 #include "chrome/browser/prerender/prerender_render_view_host_observer.h"
17 #include "chrome/browser/prerender/prerender_tracker.h" 17 #include "chrome/browser/prerender/prerender_tracker.h"
18 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_list.h" 20 #include "chrome/browser/ui/browser_list.h"
21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
22 #include "chrome/common/chrome_notification_types.h" 22 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/icon_messages.h" 23 #include "chrome/common/icon_messages.h"
24 #include "chrome/common/render_messages.h" 24 #include "chrome/common/prerender_messages.h"
25 #include "chrome/common/url_constants.h" 25 #include "chrome/common/url_constants.h"
26 #include "content/browser/renderer_host/render_view_host.h" 26 #include "content/browser/renderer_host/render_view_host.h"
27 #include "content/browser/renderer_host/resource_request_details.h" 27 #include "content/browser/renderer_host/resource_request_details.h"
28 #include "content/public/browser/browser_child_process_host.h" 28 #include "content/public/browser/browser_child_process_host.h"
29 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/render_process_host.h" 30 #include "content/public/browser/render_process_host.h"
31 #include "content/public/browser/web_contents.h" 31 #include "content/public/browser/web_contents.h"
32 #include "content/public/browser/web_contents_delegate.h" 32 #include "content/public/browser/web_contents_delegate.h"
33 #include "content/public/browser/web_contents_view.h" 33 #include "content/public/browser/web_contents_view.h"
34 #include "ui/gfx/rect.h" 34 #include "ui/gfx/rect.h"
(...skipping 16 matching lines...) Expand all
51 bool operator()(const GURL& url) const { 51 bool operator()(const GURL& url) const {
52 return url.scheme() == url_.scheme() && 52 return url.scheme() == url_.scheme() &&
53 url.host() == url_.host() && 53 url.host() == url_.host() &&
54 url.port() == url_.port() && 54 url.port() == url_.port() &&
55 url.path() == url_.path() && 55 url.path() == url_.path() &&
56 url.query() == url_.query(); 56 url.query() == url_.query();
57 } 57 }
58 GURL url_; 58 GURL url_;
59 }; 59 };
60 60
61 // Tells the render process at |child_id| whether |url| is a new prerendered
62 // page, or whether |url| is being removed as a prerendered page. Currently
63 // this will only inform the render process that created the prerendered page
64 // with <link rel="prerender"> tags about it. This means that if the user
65 // clicks on a link for a prerendered URL in a different page, the prerender
66 // will not be swapped in.
67 void InformRenderProcessAboutPrerender(const GURL& url,
68 bool is_add,
69 int child_id) {
70 if (child_id < 0)
71 return;
72 content::RenderProcessHost* render_process_host =
73 content::RenderProcessHost::FromID(child_id);
74 if (!render_process_host)
75 return;
76 IPC::Message* message = NULL;
77 if (is_add)
78 message = new PrerenderMsg_AddPrerenderURL(url);
79 else
80 message = new PrerenderMsg_RemovePrerenderURL(url);
81 render_process_host->Send(message);
82 }
83
61 } // end namespace 84 } // end namespace
62 85
63 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { 86 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
64 public: 87 public:
65 virtual PrerenderContents* CreatePrerenderContents( 88 virtual PrerenderContents* CreatePrerenderContents(
66 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, 89 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker,
67 Profile* profile, const GURL& url, const content::Referrer& referrer, 90 Profile* profile, const GURL& url, const content::Referrer& referrer,
68 Origin origin, uint8 experiment_id) OVERRIDE { 91 Origin origin, uint8 experiment_id) OVERRIDE {
69 return new PrerenderContents(prerender_manager, prerender_tracker, profile, 92 return new PrerenderContents(prerender_manager, prerender_tracker, profile,
70 url, referrer, origin, experiment_id); 93 url, referrer, origin, experiment_id);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 page_id_(0), 240 page_id_(0),
218 has_stopped_loading_(false), 241 has_stopped_loading_(false),
219 has_finished_loading_(false), 242 has_finished_loading_(false),
220 final_status_(FINAL_STATUS_MAX), 243 final_status_(FINAL_STATUS_MAX),
221 prerendering_has_started_(false), 244 prerendering_has_started_(false),
222 match_complete_status_(MATCH_COMPLETE_DEFAULT), 245 match_complete_status_(MATCH_COMPLETE_DEFAULT),
223 prerendering_has_been_cancelled_(false), 246 prerendering_has_been_cancelled_(false),
224 child_id_(-1), 247 child_id_(-1),
225 route_id_(-1), 248 route_id_(-1),
226 origin_(origin), 249 origin_(origin),
227 experiment_id_(experiment_id) { 250 experiment_id_(experiment_id),
251 creator_child_id_(-1) {
228 DCHECK(prerender_manager != NULL); 252 DCHECK(prerender_manager != NULL);
229 } 253 }
230 254
231 bool PrerenderContents::Init() { 255 bool PrerenderContents::Init() {
232 return AddAliasURL(prerender_url_); 256 return AddAliasURL(prerender_url_);
233 } 257 }
234 258
235 // static 259 // static
236 PrerenderContents::Factory* PrerenderContents::CreateFactory() { 260 PrerenderContents::Factory* PrerenderContents::CreateFactory() {
237 return new PrerenderContentsFactoryImpl(); 261 return new PrerenderContentsFactoryImpl();
238 } 262 }
239 263
240 void PrerenderContents::StartPrerendering( 264 void PrerenderContents::StartPrerendering(
241 const RenderViewHost* source_render_view_host, 265 const RenderViewHost* source_render_view_host,
242 content::SessionStorageNamespace* session_storage_namespace) { 266 content::SessionStorageNamespace* session_storage_namespace) {
243 DCHECK(profile_ != NULL); 267 DCHECK(profile_ != NULL);
244 DCHECK(!prerendering_has_started_); 268 DCHECK(!prerendering_has_started_);
245 DCHECK(prerender_contents_.get() == NULL); 269 DCHECK(prerender_contents_.get() == NULL);
246 270
247 prerendering_has_started_ = true; 271 prerendering_has_started_ = true;
272 DCHECK(creator_child_id_ == -1);
273 DCHECK(alias_urls_.size() == 1);
274 if (source_render_view_host)
275 creator_child_id_ = source_render_view_host->GetProcess()->GetID();
276 InformRenderProcessAboutPrerender(prerender_url_, true,
277 creator_child_id_);
278
248 WebContents* new_contents = WebContents::Create( 279 WebContents* new_contents = WebContents::Create(
249 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace); 280 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace);
250 prerender_contents_.reset(new TabContentsWrapper(new_contents)); 281 prerender_contents_.reset(new TabContentsWrapper(new_contents));
251 content::WebContentsObserver::Observe(new_contents); 282 content::WebContentsObserver::Observe(new_contents);
252 283
253 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds; 284 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds;
254 if (source_render_view_host) { 285 if (source_render_view_host) {
255 DCHECK(source_render_view_host->GetView() != NULL); 286 DCHECK(source_render_view_host->GetView() != NULL);
256 WebContents* source_wc = 287 WebContents* source_wc =
257 source_render_view_host->GetDelegate()->GetAsWebContents(); 288 source_render_view_host->GetDelegate()->GetAsWebContents();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 DCHECK(prerendering_has_been_cancelled_ || 384 DCHECK(prerendering_has_been_cancelled_ ||
354 final_status_ == FINAL_STATUS_USED); 385 final_status_ == FINAL_STATUS_USED);
355 DCHECK(origin_ != ORIGIN_MAX); 386 DCHECK(origin_ != ORIGIN_MAX);
356 387
357 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( 388 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus(
358 origin_, 389 origin_,
359 experiment_id_, 390 experiment_id_,
360 match_complete_status_, 391 match_complete_status_,
361 final_status_); 392 final_status_);
362 393
363 if (child_id_ != -1 && route_id_ != -1) 394 if (child_id_ != -1 && route_id_ != -1) {
364 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); 395 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_);
396 for (std::vector<GURL>::const_iterator it = alias_urls_.begin();
397 it != alias_urls_.end();
398 ++it) {
399 InformRenderProcessAboutPrerender(*it, false, creator_child_id_);
dominich 2012/03/06 19:41:39 Is there any way to pass a list in a message inste
cbentzel 2012/03/06 19:45:27 I'm not sure if the IPCs can handle a vector<GURL>
400 }
401 }
365 402
366 // If we still have a TabContents, clean up anything we need to and then 403 // If we still have a TabContents, clean up anything we need to and then
367 // destroy it. 404 // destroy it.
368 if (prerender_contents_.get()) 405 if (prerender_contents_.get())
369 delete ReleasePrerenderContents(); 406 delete ReleasePrerenderContents();
370 407
371 // The following URLs are no longer rendering. 408 // The following URLs are no longer rendering.
372 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_); 409 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_);
373 } 410 }
374 411
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 446
410 content::Details<RenderViewHost> new_render_view_host(details); 447 content::Details<RenderViewHost> new_render_view_host(details);
411 OnRenderViewHostCreated(new_render_view_host.ptr()); 448 OnRenderViewHostCreated(new_render_view_host.ptr());
412 449
413 // When a new RenderView is created for a prerendering TabContents, 450 // When a new RenderView is created for a prerendering TabContents,
414 // tell the new RenderView it's being used for prerendering before any 451 // tell the new RenderView it's being used for prerendering before any
415 // navigations occur. Note that this is always triggered before the 452 // navigations occur. Note that this is always triggered before the
416 // first navigation, so there's no need to send the message just after 453 // first navigation, so there's no need to send the message just after
417 // the TabContents is created. 454 // the TabContents is created.
418 new_render_view_host->Send( 455 new_render_view_host->Send(
419 new ChromeViewMsg_SetIsPrerendering( 456 new PrerenderMsg_SetIsPrerendering(
420 new_render_view_host->GetRoutingID(), 457 new_render_view_host->GetRoutingID(),
421 true)); 458 true));
422 459
423 // Make sure the size of the RenderViewHost has been passed to the new 460 // Make sure the size of the RenderViewHost has been passed to the new
424 // RenderView. Otherwise, the size may not be sent until the 461 // RenderView. Otherwise, the size may not be sent until the
425 // RenderViewReady event makes it from the render process to the UI 462 // RenderViewReady event makes it from the render process to the UI
426 // thread of the browser process. When the RenderView receives its 463 // thread of the browser process. When the RenderView receives its
427 // size, is also sets itself to be visible, which would then break the 464 // size, is also sets itself to be visible, which would then break the
428 // visibility API. 465 // visibility API.
429 new_render_view_host->WasResized(); 466 new_render_view_host->WasResized();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 if (https && !prerender_manager_->config().https_allowed) { 503 if (https && !prerender_manager_->config().https_allowed) {
467 Destroy(FINAL_STATUS_HTTPS); 504 Destroy(FINAL_STATUS_HTTPS);
468 return false; 505 return false;
469 } 506 }
470 if (prerender_manager_->HasRecentlyBeenNavigatedTo(url)) { 507 if (prerender_manager_->HasRecentlyBeenNavigatedTo(url)) {
471 Destroy(FINAL_STATUS_RECENTLY_VISITED); 508 Destroy(FINAL_STATUS_RECENTLY_VISITED);
472 return false; 509 return false;
473 } 510 }
474 511
475 alias_urls_.push_back(url); 512 alias_urls_.push_back(url);
513 InformRenderProcessAboutPrerender(url, true, creator_child_id_);
476 prerender_tracker_->AddPrerenderURLOnUIThread(url); 514 prerender_tracker_->AddPrerenderURLOnUIThread(url);
477 return true; 515 return true;
478 } 516 }
479 517
480 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( 518 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents(
481 PrerenderContents* other_pc) { 519 PrerenderContents* other_pc) {
482 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin(); 520 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin();
483 it != other_pc->alias_urls_.end(); 521 it != other_pc->alias_urls_.end();
484 ++it) { 522 ++it) {
485 alias_urls_.push_back(*it); 523 alias_urls_.push_back(*it);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 bool PrerenderContents::IsCrossSiteNavigationPending() const { 694 bool PrerenderContents::IsCrossSiteNavigationPending() const {
657 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) 695 if (!prerender_contents_.get() || !prerender_contents_->web_contents())
658 return false; 696 return false;
659 const WebContents* web_contents = prerender_contents_->web_contents(); 697 const WebContents* web_contents = prerender_contents_->web_contents();
660 return (web_contents->GetSiteInstance() != 698 return (web_contents->GetSiteInstance() !=
661 web_contents->GetPendingSiteInstance()); 699 web_contents->GetPendingSiteInstance());
662 } 700 }
663 701
664 702
665 } // namespace prerender 703 } // namespace prerender
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_contents.h ('k') | chrome/browser/prerender/prerender_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698