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

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: Remove TODO 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/in_process_webkit/session_storage_namespace.h" 26 #include "content/browser/in_process_webkit/session_storage_namespace.h"
27 #include "content/browser/renderer_host/render_view_host.h" 27 #include "content/browser/renderer_host/render_view_host.h"
28 #include "content/browser/renderer_host/resource_request_details.h" 28 #include "content/browser/renderer_host/resource_request_details.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 20 matching lines...) Expand all
55 bool operator()(const GURL& url) const { 55 bool operator()(const GURL& url) const {
56 return url.scheme() == url_.scheme() && 56 return url.scheme() == url_.scheme() &&
57 url.host() == url_.host() && 57 url.host() == url_.host() &&
58 url.port() == url_.port() && 58 url.port() == url_.port() &&
59 url.path() == url_.path() && 59 url.path() == url_.path() &&
60 url.query() == url_.query(); 60 url.query() == url_.query();
61 } 61 }
62 GURL url_; 62 GURL url_;
63 }; 63 };
64 64
65 // Tells the render process at |child_id| whether |url| is a new prerendered
66 // page, or whether |url| is being removed as a prerendered page. Currently
67 // this will only inform the render process that created the prerendered page
68 // with <link rel="prerender"> tags about it. This means that if the user
69 // clicks on a link for a prerendered URL in a different page, the prerender
70 // will not be swapped in.
71 void InformRenderProcessAboutPrerender(const GURL& url,
72 bool is_add,
73 int child_id) {
74 if (child_id < 0)
75 return;
76 content::RenderProcessHost* render_process_host =
77 content::RenderProcessHost::FromID(child_id);
78 if (!render_process_host)
79 return;
80 IPC::Message* message = NULL;
81 if (is_add)
82 message = new PrerenderMsg_AddPrerenderURL(url);
83 else
84 message = new PrerenderMsg_RemovePrerenderURL(url);
85 render_process_host->Send(message);
86 }
87
65 } // end namespace 88 } // end namespace
66 89
67 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { 90 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
68 public: 91 public:
69 virtual PrerenderContents* CreatePrerenderContents( 92 virtual PrerenderContents* CreatePrerenderContents(
70 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, 93 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker,
71 Profile* profile, const GURL& url, const content::Referrer& referrer, 94 Profile* profile, const GURL& url, const content::Referrer& referrer,
72 Origin origin, uint8 experiment_id) OVERRIDE { 95 Origin origin, uint8 experiment_id) OVERRIDE {
73 return new PrerenderContents(prerender_manager, prerender_tracker, profile, 96 return new PrerenderContents(prerender_manager, prerender_tracker, profile,
74 url, referrer, origin, experiment_id); 97 url, referrer, origin, experiment_id);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 profile_(profile), 243 profile_(profile),
221 page_id_(0), 244 page_id_(0),
222 has_stopped_loading_(false), 245 has_stopped_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 SessionStorageNamespace* session_storage_namespace) { 269 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; 286 gfx::Rect 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 DCHECK(prerendering_has_been_cancelled_ || 385 DCHECK(prerendering_has_been_cancelled_ ||
356 final_status_ == FINAL_STATUS_USED); 386 final_status_ == FINAL_STATUS_USED);
357 DCHECK(origin_ != ORIGIN_MAX); 387 DCHECK(origin_ != ORIGIN_MAX);
358 388
359 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( 389 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus(
360 origin_, 390 origin_,
361 experiment_id_, 391 experiment_id_,
362 match_complete_status_, 392 match_complete_status_,
363 final_status_); 393 final_status_);
364 394
365 if (child_id_ != -1 && route_id_ != -1) 395 if (child_id_ != -1 && route_id_ != -1) {
366 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); 396 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_);
397 InformRenderProcessAboutPrerender(prerender_url_, false, creator_child_id_);
398 }
367 399
368 // If we still have a TabContents, clean up anything we need to and then 400 // If we still have a TabContents, clean up anything we need to and then
369 // destroy it. 401 // destroy it.
370 if (prerender_contents_.get()) 402 if (prerender_contents_.get())
371 delete ReleasePrerenderContents(); 403 delete ReleasePrerenderContents();
372 404
373 // The following URLs are no longer rendering. 405 // The following URLs are no longer rendering.
374 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_); 406 prerender_tracker_->RemovePrerenderURLsOnUIThread(alias_urls_);
375 } 407 }
376 408
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 443
412 content::Details<RenderViewHost> new_render_view_host(details); 444 content::Details<RenderViewHost> new_render_view_host(details);
413 OnRenderViewHostCreated(new_render_view_host.ptr()); 445 OnRenderViewHostCreated(new_render_view_host.ptr());
414 446
415 // When a new RenderView is created for a prerendering TabContents, 447 // When a new RenderView is created for a prerendering TabContents,
416 // tell the new RenderView it's being used for prerendering before any 448 // tell the new RenderView it's being used for prerendering before any
417 // navigations occur. Note that this is always triggered before the 449 // navigations occur. Note that this is always triggered before the
418 // first navigation, so there's no need to send the message just after 450 // first navigation, so there's no need to send the message just after
419 // the TabContents is created. 451 // the TabContents is created.
420 new_render_view_host->Send( 452 new_render_view_host->Send(
421 new ChromeViewMsg_SetIsPrerendering( 453 new PrerenderMsg_SetIsPrerendering(
422 new_render_view_host->routing_id(), 454 new_render_view_host->routing_id(),
423 true)); 455 true));
424 456
425 // Make sure the size of the RenderViewHost has been passed to the new 457 // Make sure the size of the RenderViewHost has been passed to the new
426 // RenderView. Otherwise, the size may not be sent until the 458 // RenderView. Otherwise, the size may not be sent until the
427 // RenderViewReady event makes it from the render process to the UI 459 // RenderViewReady event makes it from the render process to the UI
428 // thread of the browser process. When the RenderView receives its 460 // thread of the browser process. When the RenderView receives its
429 // size, is also sets itself to be visible, which would then break the 461 // size, is also sets itself to be visible, which would then break the
430 // visibility API. 462 // visibility API.
431 new_render_view_host->WasResized(); 463 new_render_view_host->WasResized();
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 bool PrerenderContents::IsCrossSiteNavigationPending() const { 682 bool PrerenderContents::IsCrossSiteNavigationPending() const {
651 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) 683 if (!prerender_contents_.get() || !prerender_contents_->web_contents())
652 return false; 684 return false;
653 const WebContents* web_contents = prerender_contents_->web_contents(); 685 const WebContents* web_contents = prerender_contents_->web_contents();
654 return (web_contents->GetSiteInstance() != 686 return (web_contents->GetSiteInstance() !=
655 web_contents->GetPendingSiteInstance()); 687 web_contents->GetPendingSiteInstance());
656 } 688 }
657 689
658 690
659 } // namespace prerender 691 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698