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 |