| 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 <functional> | 8 #include <functional> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 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/session_storage_namespace.h" | 31 #include "content/public/browser/session_storage_namespace.h" |
| 32 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 33 #include "content/public/browser/web_contents_delegate.h" | 33 #include "content/public/browser/web_contents_delegate.h" |
| 34 #include "content/public/browser/web_contents_view.h" | 34 #include "content/public/browser/web_contents_view.h" |
| 35 #include "ui/gfx/rect.h" | 35 #include "ui/gfx/rect.h" |
| 36 | 36 |
| 37 using content::DownloadItem; | 37 using content::DownloadItem; |
| 38 using content::OpenURLParams; | 38 using content::OpenURLParams; |
| 39 using content::RenderProcessHost; |
| 39 using content::RenderViewHost; | 40 using content::RenderViewHost; |
| 40 using content::ResourceRedirectDetails; | 41 using content::ResourceRedirectDetails; |
| 41 using content::SessionStorageNamespace; | 42 using content::SessionStorageNamespace; |
| 42 using content::WebContents; | 43 using content::WebContents; |
| 43 | 44 |
| 44 namespace prerender { | 45 namespace prerender { |
| 45 | 46 |
| 46 namespace { | |
| 47 | |
| 48 // Tells the render process at |child_id| whether |url| is a new prerendered | |
| 49 // page, or whether |url| is being removed as a prerendered page. Currently | |
| 50 // this will only inform the render process that created the prerendered page | |
| 51 // with <link rel="prerender"> tags about it. This means that if the user | |
| 52 // clicks on a link for a prerendered URL in a different page, the prerender | |
| 53 // will not be swapped in. | |
| 54 void InformRenderProcessAboutPrerender(const GURL& url, | |
| 55 bool is_add, | |
| 56 int child_id) { | |
| 57 if (child_id < 0) | |
| 58 return; | |
| 59 content::RenderProcessHost* render_process_host = | |
| 60 content::RenderProcessHost::FromID(child_id); | |
| 61 if (!render_process_host) | |
| 62 return; | |
| 63 IPC::Message* message = NULL; | |
| 64 if (is_add) | |
| 65 message = new PrerenderMsg_AddPrerenderURL(url); | |
| 66 else | |
| 67 message = new PrerenderMsg_RemovePrerenderURL(url); | |
| 68 render_process_host->Send(message); | |
| 69 } | |
| 70 | |
| 71 } // namespace | |
| 72 | |
| 73 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { | 47 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { |
| 74 public: | 48 public: |
| 75 virtual PrerenderContents* CreatePrerenderContents( | 49 virtual PrerenderContents* CreatePrerenderContents( |
| 76 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, | 50 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, |
| 77 Profile* profile, const GURL& url, const content::Referrer& referrer, | 51 Profile* profile, const GURL& url, const content::Referrer& referrer, |
| 78 Origin origin, uint8 experiment_id) OVERRIDE { | 52 Origin origin, uint8 experiment_id) OVERRIDE { |
| 79 return new PrerenderContents(prerender_manager, prerender_tracker, profile, | 53 return new PrerenderContents(prerender_manager, prerender_tracker, profile, |
| 80 url, referrer, origin, experiment_id); | 54 url, referrer, origin, experiment_id); |
| 81 } | 55 } |
| 82 }; | 56 }; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 return AddAliasURL(prerender_url_); | 261 return AddAliasURL(prerender_url_); |
| 288 } | 262 } |
| 289 | 263 |
| 290 // static | 264 // static |
| 291 PrerenderContents::Factory* PrerenderContents::CreateFactory() { | 265 PrerenderContents::Factory* PrerenderContents::CreateFactory() { |
| 292 return new PrerenderContentsFactoryImpl(); | 266 return new PrerenderContentsFactoryImpl(); |
| 293 } | 267 } |
| 294 | 268 |
| 295 void PrerenderContents::StartPrerendering( | 269 void PrerenderContents::StartPrerendering( |
| 296 int creator_child_id, | 270 int creator_child_id, |
| 271 int prerender_id, |
| 297 const gfx::Size& size, | 272 const gfx::Size& size, |
| 298 SessionStorageNamespace* session_storage_namespace, | 273 SessionStorageNamespace* session_storage_namespace, |
| 299 bool is_control_group) { | 274 bool is_control_group) { |
| 300 DCHECK(profile_ != NULL); | 275 DCHECK(profile_ != NULL); |
| 301 DCHECK(!size.IsEmpty()); | 276 DCHECK(!size.IsEmpty()); |
| 302 DCHECK(!prerendering_has_started_); | 277 DCHECK(!prerendering_has_started_); |
| 303 DCHECK(prerender_contents_.get() == NULL); | 278 DCHECK(prerender_contents_.get() == NULL); |
| 304 DCHECK_EQ(-1, creator_child_id_); | 279 DCHECK_EQ(-1, creator_child_id_); |
| 305 DCHECK(size_.IsEmpty()); | 280 DCHECK(size_.IsEmpty()); |
| 306 DCHECK_EQ(1U, alias_urls_.size()); | 281 DCHECK_EQ(1U, alias_urls_.size()); |
| 307 | 282 |
| 308 creator_child_id_ = creator_child_id; | 283 creator_child_id_ = creator_child_id; |
| 284 prerender_id_ = prerender_id; |
| 309 session_storage_namespace_id_ = session_storage_namespace->id(); | 285 session_storage_namespace_id_ = session_storage_namespace->id(); |
| 310 size_ = size; | 286 size_ = size; |
| 311 | 287 |
| 312 InformRenderProcessAboutPrerender(prerender_url_, true, | 288 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
| 313 creator_child_id_); | 289 host->Send(new PrerenderMsg_StartedPrerender(prerender_id_)); |
| 314 | 290 |
| 315 DCHECK(load_start_time_.is_null()); | 291 DCHECK(load_start_time_.is_null()); |
| 316 load_start_time_ = base::TimeTicks::Now(); | 292 load_start_time_ = base::TimeTicks::Now(); |
| 317 | 293 |
| 318 // Everything after this point sets up the WebContents object and associated | 294 // Everything after this point sets up the WebContents object and associated |
| 319 // RenderView for the prerender page. Don't do this for members of the | 295 // RenderView for the prerender page. Don't do this for members of the |
| 320 // control group. | 296 // control group. |
| 321 if (is_control_group) | 297 if (is_control_group) |
| 322 return; | 298 return; |
| 323 | 299 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 } | 378 } |
| 403 | 379 |
| 404 void PrerenderContents::set_final_status(FinalStatus final_status) { | 380 void PrerenderContents::set_final_status(FinalStatus final_status) { |
| 405 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); | 381 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); |
| 406 DCHECK(final_status_ == FINAL_STATUS_MAX); | 382 DCHECK(final_status_ == FINAL_STATUS_MAX); |
| 407 | 383 |
| 408 final_status_ = final_status; | 384 final_status_ = final_status; |
| 409 } | 385 } |
| 410 | 386 |
| 411 PrerenderContents::~PrerenderContents() { | 387 PrerenderContents::~PrerenderContents() { |
| 412 DCHECK(final_status_ != FINAL_STATUS_MAX); | 388 DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
| 413 DCHECK(prerendering_has_been_cancelled_ || | 389 DCHECK( |
| 414 final_status_ == FINAL_STATUS_USED); | 390 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED); |
| 415 DCHECK(origin_ != ORIGIN_MAX); | 391 DCHECK_NE(ORIGIN_MAX, origin_); |
| 416 | 392 |
| 417 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( | 393 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( |
| 418 origin_, | 394 origin_, experiment_id_, match_complete_status_, final_status_); |
| 419 experiment_id_, | |
| 420 match_complete_status_, | |
| 421 final_status_); | |
| 422 | 395 |
| 423 if (child_id_ != -1 && route_id_ != -1) { | 396 if (child_id_ != -1 && route_id_ != -1) { |
| 424 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); | 397 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); |
| 425 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); | 398 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
| 426 it != alias_urls_.end(); | 399 host->Send(new PrerenderMsg_StoppedPrerender(prerender_id_)); |
| 427 ++it) { | |
| 428 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); | |
| 429 } | |
| 430 } | 400 } |
| 431 | 401 |
| 432 // If we still have a WebContents, clean up anything we need to and then | 402 // If we still have a WebContents, clean up anything we need to and then |
| 433 // destroy it. | 403 // destroy it. |
| 434 if (prerender_contents_.get()) | 404 if (prerender_contents_.get()) |
| 435 delete ReleasePrerenderContents(); | 405 delete ReleasePrerenderContents(); |
| 436 } | 406 } |
| 437 | 407 |
| 438 void PrerenderContents::Observe(int type, | 408 void PrerenderContents::Observe(int type, |
| 439 const content::NotificationSource& source, | 409 const content::NotificationSource& source, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 Destroy(FINAL_STATUS_HTTPS); | 512 Destroy(FINAL_STATUS_HTTPS); |
| 543 return false; | 513 return false; |
| 544 } | 514 } |
| 545 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && | 515 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && |
| 546 prerender_manager_->HasRecentlyBeenNavigatedTo(url)) { | 516 prerender_manager_->HasRecentlyBeenNavigatedTo(url)) { |
| 547 Destroy(FINAL_STATUS_RECENTLY_VISITED); | 517 Destroy(FINAL_STATUS_RECENTLY_VISITED); |
| 548 return false; | 518 return false; |
| 549 } | 519 } |
| 550 | 520 |
| 551 alias_urls_.push_back(url); | 521 alias_urls_.push_back(url); |
| 552 InformRenderProcessAboutPrerender(url, true, creator_child_id_); | 522 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
| 523 host->Send(new PrerenderMsg_AddAliasToPrerender(prerender_id_, url)); |
| 553 return true; | 524 return true; |
| 554 } | 525 } |
| 555 | 526 |
| 556 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( | 527 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( |
| 557 PrerenderContents* other_pc) { | 528 PrerenderContents* other_pc) { |
| 558 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin(); | 529 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin(); |
| 559 it != other_pc->alias_urls_.end(); | 530 it != other_pc->alias_urls_.end(); |
| 560 ++it) { | 531 ++it) { |
| 561 alias_urls_.push_back(*it); | 532 alias_urls_.push_back(*it); |
| 562 } | 533 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 689 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
| 719 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 690 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) |
| 720 return false; | 691 return false; |
| 721 const WebContents* web_contents = prerender_contents_->web_contents(); | 692 const WebContents* web_contents = prerender_contents_->web_contents(); |
| 722 return (web_contents->GetSiteInstance() != | 693 return (web_contents->GetSiteInstance() != |
| 723 web_contents->GetPendingSiteInstance()); | 694 web_contents->GetPendingSiteInstance()); |
| 724 } | 695 } |
| 725 | 696 |
| 726 | 697 |
| 727 } // namespace prerender | 698 } // namespace prerender |
| OLD | NEW |