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

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

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

Powered by Google App Engine
This is Rietveld 408576698