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

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: Fix unit tests 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/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/web_contents.h" 30 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_delegate.h" 31 #include "content/public/browser/web_contents_delegate.h"
32 #include "content/public/browser/web_contents_view.h" 32 #include "content/public/browser/web_contents_view.h"
33 #include "ui/gfx/rect.h" 33 #include "ui/gfx/rect.h"
34 34
(...skipping 19 matching lines...) Expand all
54 bool operator()(const GURL& url) const { 54 bool operator()(const GURL& url) const {
55 return url.scheme() == url_.scheme() && 55 return url.scheme() == url_.scheme() &&
56 url.host() == url_.host() && 56 url.host() == url_.host() &&
57 url.port() == url_.port() && 57 url.port() == url_.port() &&
58 url.path() == url_.path() && 58 url.path() == url_.path() &&
59 url.query() == url_.query(); 59 url.query() == url_.query();
60 } 60 }
61 GURL url_; 61 GURL url_;
62 }; 62 };
63 63
64 // Tells the render process at |child_id| whether |url| is a new prerendered
65 // page, or whether |url| is being removed as a prerendered page. Currently
66 // this will only inform the render process that created the prerendered page
67 // with <link rel="prerender"> tags about it. This means that if the user
68 // clicks on a link for a prerendered URL in a different page, the prerender
69 // will not be swapped in.
Charlie Reis 2012/03/01 19:06:03 I think this is the right call. For reference, we
70 void InformRenderProcessAboutPrerender(const GURL& url,
71 bool is_add,
72 int child_id) {
73 if (child_id < 0)
74 return;
75 content::RenderProcessHost* render_process_host =
76 content::RenderProcessHost::FromID(child_id);
77 if (!render_process_host)
78 return;
79 IPC::Message* message = NULL;
80 if (is_add)
81 message = new PrerenderMsg_AddPrerenderURL(url);
82 else
83 message = new PrerenderMsg_RemovePrerenderURL(url);
Charlie Reis 2012/03/01 19:06:03 Just as a sanity check, we don't need to be concer
cbentzel 2012/03/01 22:18:53 You are correct - there is not a race here. I com
Charlie Reis 2012/03/01 22:24:38 That comment is sufficient, thanks. This file jus
84 render_process_host->Send(message);
85 }
86
64 } // end namespace 87 } // end namespace
65 88
66 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { 89 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
67 public: 90 public:
68 virtual PrerenderContents* CreatePrerenderContents( 91 virtual PrerenderContents* CreatePrerenderContents(
69 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, 92 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker,
70 Profile* profile, const GURL& url, const content::Referrer& referrer, 93 Profile* profile, const GURL& url, const content::Referrer& referrer,
71 Origin origin, uint8 experiment_id) OVERRIDE { 94 Origin origin, uint8 experiment_id) OVERRIDE {
72 return new PrerenderContents(prerender_manager, prerender_tracker, profile, 95 return new PrerenderContents(prerender_manager, prerender_tracker, profile,
73 url, referrer, origin, experiment_id); 96 url, referrer, origin, experiment_id);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 page_id_(0), 243 page_id_(0),
221 has_stopped_loading_(false), 244 has_stopped_loading_(false),
222 has_finished_loading_(false), 245 has_finished_loading_(false),
223 final_status_(FINAL_STATUS_MAX), 246 final_status_(FINAL_STATUS_MAX),
224 prerendering_has_started_(false), 247 prerendering_has_started_(false),
225 match_complete_status_(MATCH_COMPLETE_DEFAULT), 248 match_complete_status_(MATCH_COMPLETE_DEFAULT),
226 prerendering_has_been_cancelled_(false), 249 prerendering_has_been_cancelled_(false),
227 child_id_(-1), 250 child_id_(-1),
228 route_id_(-1), 251 route_id_(-1),
229 origin_(origin), 252 origin_(origin),
230 experiment_id_(experiment_id) { 253 experiment_id_(experiment_id),
254 creator_child_id_(-1) {
231 DCHECK(prerender_manager != NULL); 255 DCHECK(prerender_manager != NULL);
232 } 256 }
233 257
234 bool PrerenderContents::Init() { 258 bool PrerenderContents::Init() {
235 return AddAliasURL(prerender_url_); 259 return AddAliasURL(prerender_url_);
236 } 260 }
237 261
238 // static 262 // static
239 PrerenderContents::Factory* PrerenderContents::CreateFactory() { 263 PrerenderContents::Factory* PrerenderContents::CreateFactory() {
240 return new PrerenderContentsFactoryImpl(); 264 return new PrerenderContentsFactoryImpl();
241 } 265 }
242 266
243 void PrerenderContents::StartPrerendering( 267 void PrerenderContents::StartPrerendering(
244 const RenderViewHost* source_render_view_host, 268 const RenderViewHost* source_render_view_host,
245 content::SessionStorageNamespace* session_storage_namespace) { 269 content::SessionStorageNamespace* session_storage_namespace) {
246 DCHECK(profile_ != NULL); 270 DCHECK(profile_ != NULL);
247 DCHECK(!prerendering_has_started_); 271 DCHECK(!prerendering_has_started_);
248 DCHECK(prerender_contents_.get() == NULL); 272 DCHECK(prerender_contents_.get() == NULL);
249 273
250 prerendering_has_started_ = true; 274 prerendering_has_started_ = true;
275 DCHECK(creator_child_id_ == -1);
276 if (source_render_view_host)
277 creator_child_id_ = source_render_view_host->process()->GetID();
278 InformRenderProcessAboutPrerender(prerender_url_, true,
279 creator_child_id_);
280
251 WebContents* new_contents = WebContents::Create( 281 WebContents* new_contents = WebContents::Create(
252 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace); 282 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace);
253 prerender_contents_.reset(new TabContentsWrapper(new_contents)); 283 prerender_contents_.reset(new TabContentsWrapper(new_contents));
254 content::WebContentsObserver::Observe(new_contents); 284 content::WebContentsObserver::Observe(new_contents);
255 285
256 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds; 286 gfx::Rect tab_bounds = prerender_manager_->config().default_tab_bounds;
257 if (source_render_view_host) { 287 if (source_render_view_host) {
258 DCHECK(source_render_view_host->view() != NULL); 288 DCHECK(source_render_view_host->view() != NULL);
259 WebContents* source_wc = 289 WebContents* source_wc =
260 source_render_view_host->delegate()->GetAsWebContents(); 290 source_render_view_host->delegate()->GetAsWebContents();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 DCHECK(prerendering_has_been_cancelled_ || 386 DCHECK(prerendering_has_been_cancelled_ ||
357 final_status_ == FINAL_STATUS_USED); 387 final_status_ == FINAL_STATUS_USED);
358 DCHECK(origin_ != ORIGIN_MAX); 388 DCHECK(origin_ != ORIGIN_MAX);
359 389
360 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( 390 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus(
361 origin_, 391 origin_,
362 experiment_id_, 392 experiment_id_,
363 match_complete_status_, 393 match_complete_status_,
364 final_status_); 394 final_status_);
365 395
366 if (child_id_ != -1 && route_id_ != -1) 396 if (child_id_ != -1 && route_id_ != -1) {
367 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); 397 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_);
398 InformRenderProcessAboutPrerender(prerender_url_, false, creator_child_id_);
399 }
368 400
369 // If we still have a TabContents, clean up anything we need to and then 401 // If we still have a TabContents, clean up anything we need to and then
370 // destroy it. 402 // destroy it.
371 if (prerender_contents_.get()) 403 if (prerender_contents_.get())
372 delete ReleasePrerenderContents(); 404 delete ReleasePrerenderContents();
373 405
374 // The following URLs are no longer rendering. 406 // The following URLs are no longer rendering.
375 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_); 407 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_);
376 } 408 }
377 409
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 444
413 content::Details<RenderViewHost> new_render_view_host(details); 445 content::Details<RenderViewHost> new_render_view_host(details);
414 OnRenderViewHostCreated(new_render_view_host.ptr()); 446 OnRenderViewHostCreated(new_render_view_host.ptr());
415 447
416 // When a new RenderView is created for a prerendering TabContents, 448 // When a new RenderView is created for a prerendering TabContents,
417 // tell the new RenderView it's being used for prerendering before any 449 // tell the new RenderView it's being used for prerendering before any
418 // navigations occur. Note that this is always triggered before the 450 // navigations occur. Note that this is always triggered before the
419 // first navigation, so there's no need to send the message just after 451 // first navigation, so there's no need to send the message just after
420 // the TabContents is created. 452 // the TabContents is created.
421 new_render_view_host->Send( 453 new_render_view_host->Send(
422 new ChromeViewMsg_SetIsPrerendering( 454 new PrerenderMsg_SetIsPrerendering(
423 new_render_view_host->routing_id(), 455 new_render_view_host->routing_id(),
424 true)); 456 true));
425 457
426 // Make sure the size of the RenderViewHost has been passed to the new 458 // Make sure the size of the RenderViewHost has been passed to the new
427 // RenderView. Otherwise, the size may not be sent until the 459 // RenderView. Otherwise, the size may not be sent until the
428 // RenderViewReady event makes it from the render process to the UI 460 // RenderViewReady event makes it from the render process to the UI
429 // thread of the browser process. When the RenderView receives its 461 // thread of the browser process. When the RenderView receives its
430 // size, is also sets itself to be visible, which would then break the 462 // size, is also sets itself to be visible, which would then break the
431 // visibility API. 463 // visibility API.
432 new_render_view_host->WasResized(); 464 new_render_view_host->WasResized();
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 bool PrerenderContents::IsCrossSiteNavigationPending() const { 691 bool PrerenderContents::IsCrossSiteNavigationPending() const {
660 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) 692 if (!prerender_contents_.get() || !prerender_contents_->web_contents())
661 return false; 693 return false;
662 const WebContents* web_contents = prerender_contents_->web_contents(); 694 const WebContents* web_contents = prerender_contents_->web_contents();
663 return (web_contents->GetSiteInstance() != 695 return (web_contents->GetSiteInstance() !=
664 web_contents->GetPendingSiteInstance()); 696 web_contents->GetPendingSiteInstance());
665 } 697 }
666 698
667 699
668 } // namespace prerender 700 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698