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 |
11 #include "base/process_util.h" | |
12 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/history/history_tab_helper.h" | 12 #include "chrome/browser/history/history_tab_helper.h" |
14 #include "chrome/browser/history/history_types.h" | 13 #include "chrome/browser/history/history_types.h" |
15 #include "chrome/browser/prerender/prerender_final_status.h" | 14 #include "chrome/browser/prerender/prerender_final_status.h" |
16 #include "chrome/browser/prerender/prerender_handle.h" | 15 #include "chrome/browser/prerender/prerender_handle.h" |
17 #include "chrome/browser/prerender/prerender_manager.h" | 16 #include "chrome/browser/prerender/prerender_manager.h" |
18 #include "chrome/browser/prerender/prerender_render_view_host_observer.h" | 17 #include "chrome/browser/prerender/prerender_render_view_host_observer.h" |
19 #include "chrome/browser/prerender/prerender_tracker.h" | 18 #include "chrome/browser/prerender/prerender_tracker.h" |
20 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
21 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 20 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
(...skipping 14 matching lines...) Expand all Loading... |
36 | 35 |
37 using content::DownloadItem; | 36 using content::DownloadItem; |
38 using content::OpenURLParams; | 37 using content::OpenURLParams; |
39 using content::RenderViewHost; | 38 using content::RenderViewHost; |
40 using content::ResourceRedirectDetails; | 39 using content::ResourceRedirectDetails; |
41 using content::SessionStorageNamespace; | 40 using content::SessionStorageNamespace; |
42 using content::WebContents; | 41 using content::WebContents; |
43 | 42 |
44 namespace prerender { | 43 namespace prerender { |
45 | 44 |
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 { | 45 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { |
74 public: | 46 public: |
75 virtual PrerenderContents* CreatePrerenderContents( | 47 virtual PrerenderContents* CreatePrerenderContents( |
76 PrerenderManager* prerender_manager, Profile* profile, | 48 PrerenderManager* prerender_manager, Profile* profile, |
77 const GURL& url, const content::Referrer& referrer, | 49 const GURL& url, const content::Referrer& referrer, |
78 Origin origin, uint8 experiment_id) OVERRIDE { | 50 Origin origin, uint8 experiment_id) OVERRIDE { |
79 return new PrerenderContents(prerender_manager, profile, | 51 return new PrerenderContents(prerender_manager, profile, |
80 url, referrer, origin, experiment_id); | 52 url, referrer, origin, experiment_id); |
81 } | 53 } |
82 }; | 54 }; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 bool user_gesture) OVERRIDE { | 132 bool user_gesture) OVERRIDE { |
161 // TODO(mmenke): Consider supporting this if it is a common case during | 133 // TODO(mmenke): Consider supporting this if it is a common case during |
162 // prerenders. | 134 // prerenders. |
163 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); | 135 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); |
164 } | 136 } |
165 | 137 |
166 private: | 138 private: |
167 PrerenderContents* prerender_contents_; | 139 PrerenderContents* prerender_contents_; |
168 }; | 140 }; |
169 | 141 |
| 142 void PrerenderContents::Observer::OnPrerenderAddAlias( |
| 143 PrerenderContents* contents, |
| 144 const GURL& alias_url) { |
| 145 } |
| 146 |
170 PrerenderContents::Observer::Observer() { | 147 PrerenderContents::Observer::Observer() { |
171 } | 148 } |
172 | 149 |
173 PrerenderContents::Observer::~Observer() { | 150 PrerenderContents::Observer::~Observer() { |
174 } | 151 } |
175 | 152 |
176 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( | 153 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( |
177 base::WeakPtr<PrerenderHandle> weak_prerender_handle, | 154 base::WeakPtr<PrerenderHandle> weak_prerender_handle, |
178 Origin origin, | 155 Origin origin, |
179 const GURL& url, | 156 const GURL& url, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 DCHECK(!prerendering_has_started_); | 248 DCHECK(!prerendering_has_started_); |
272 DCHECK(prerender_contents_.get() == NULL); | 249 DCHECK(prerender_contents_.get() == NULL); |
273 DCHECK_EQ(-1, creator_child_id_); | 250 DCHECK_EQ(-1, creator_child_id_); |
274 DCHECK(size_.IsEmpty()); | 251 DCHECK(size_.IsEmpty()); |
275 DCHECK_EQ(1U, alias_urls_.size()); | 252 DCHECK_EQ(1U, alias_urls_.size()); |
276 | 253 |
277 creator_child_id_ = creator_child_id; | 254 creator_child_id_ = creator_child_id; |
278 session_storage_namespace_id_ = session_storage_namespace->id(); | 255 session_storage_namespace_id_ = session_storage_namespace->id(); |
279 size_ = size; | 256 size_ = size; |
280 | 257 |
281 InformRenderProcessAboutPrerender(prerender_url_, true, | |
282 creator_child_id_); | |
283 | |
284 DCHECK(load_start_time_.is_null()); | 258 DCHECK(load_start_time_.is_null()); |
285 load_start_time_ = base::TimeTicks::Now(); | 259 load_start_time_ = base::TimeTicks::Now(); |
286 | 260 |
287 // Everything after this point sets up the WebContents object and associated | 261 // Everything after this point sets up the WebContents object and associated |
288 // RenderView for the prerender page. Don't do this for members of the | 262 // RenderView for the prerender page. Don't do this for members of the |
289 // control group. | 263 // control group. |
290 if (is_control_group) | 264 if (is_control_group) |
291 return; | 265 return; |
292 | 266 |
293 prerendering_has_started_ = true; | 267 prerendering_has_started_ = true; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 354 |
381 PrerenderContents::~PrerenderContents() { | 355 PrerenderContents::~PrerenderContents() { |
382 DCHECK_NE(FINAL_STATUS_MAX, final_status_); | 356 DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
383 DCHECK( | 357 DCHECK( |
384 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED); | 358 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED); |
385 DCHECK_NE(ORIGIN_MAX, origin_); | 359 DCHECK_NE(ORIGIN_MAX, origin_); |
386 | 360 |
387 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( | 361 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( |
388 origin_, experiment_id_, match_complete_status_, final_status_); | 362 origin_, experiment_id_, match_complete_status_, final_status_); |
389 | 363 |
390 if (child_id_ != -1 && route_id_ != -1) { | |
391 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); | |
392 it != alias_urls_.end(); | |
393 ++it) { | |
394 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); | |
395 } | |
396 } | |
397 | |
398 // If we still have a WebContents, clean up anything we need to and then | 364 // If we still have a WebContents, clean up anything we need to and then |
399 // destroy it. | 365 // destroy it. |
400 if (prerender_contents_.get()) | 366 if (prerender_contents_.get()) |
401 delete ReleasePrerenderContents(); | 367 delete ReleasePrerenderContents(); |
402 } | 368 } |
403 | 369 |
404 void PrerenderContents::AddObserver(Observer* observer) { | 370 void PrerenderContents::AddObserver(Observer* observer) { |
405 DCHECK_EQ(FINAL_STATUS_MAX, final_status_); | 371 DCHECK_EQ(FINAL_STATUS_MAX, final_status_); |
406 observer_list_.AddObserver(observer); | 372 observer_list_.AddObserver(observer); |
407 } | 373 } |
408 | 374 |
| 375 void PrerenderContents::RemoveObserver(Observer* observer) { |
| 376 observer_list_.RemoveObserver(observer); |
| 377 } |
| 378 |
409 void PrerenderContents::Observe(int type, | 379 void PrerenderContents::Observe(int type, |
410 const content::NotificationSource& source, | 380 const content::NotificationSource& source, |
411 const content::NotificationDetails& details) { | 381 const content::NotificationDetails& details) { |
412 switch (type) { | 382 switch (type) { |
413 case chrome::NOTIFICATION_PROFILE_DESTROYED: | 383 case chrome::NOTIFICATION_PROFILE_DESTROYED: |
414 Destroy(FINAL_STATUS_PROFILE_DESTROYED); | 384 Destroy(FINAL_STATUS_PROFILE_DESTROYED); |
415 return; | 385 return; |
416 | 386 |
417 case chrome::NOTIFICATION_APP_TERMINATING: | 387 case chrome::NOTIFICATION_APP_TERMINATING: |
418 Destroy(FINAL_STATUS_APP_TERMINATING); | 388 Destroy(FINAL_STATUS_APP_TERMINATING); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 DCHECK_EQ(FINAL_STATUS_MAX, final_status_); | 464 DCHECK_EQ(FINAL_STATUS_MAX, final_status_); |
495 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStart(this)); | 465 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStart(this)); |
496 } | 466 } |
497 | 467 |
498 void PrerenderContents::NotifyPrerenderStop() { | 468 void PrerenderContents::NotifyPrerenderStop() { |
499 DCHECK_NE(FINAL_STATUS_MAX, final_status_); | 469 DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
500 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStop(this)); | 470 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStop(this)); |
501 observer_list_.Clear(); | 471 observer_list_.Clear(); |
502 } | 472 } |
503 | 473 |
| 474 void PrerenderContents::NotifyPrerenderAddAlias(const GURL& alias_url) { |
| 475 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderAddAlias(this, |
| 476 alias_url)); |
| 477 } |
| 478 |
504 void PrerenderContents::OnUpdateFaviconURL( | 479 void PrerenderContents::OnUpdateFaviconURL( |
505 int32 page_id, | 480 int32 page_id, |
506 const std::vector<FaviconURL>& urls) { | 481 const std::vector<FaviconURL>& urls) { |
507 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; | 482 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; |
508 for (std::vector<FaviconURL>::const_iterator it = urls.begin(); | 483 for (std::vector<FaviconURL>::const_iterator it = urls.begin(); |
509 it != urls.end(); ++it) { | 484 it != urls.end(); ++it) { |
510 if (it->icon_type == FaviconURL::FAVICON) { | 485 if (it->icon_type == FaviconURL::FAVICON) { |
511 icon_url_ = it->icon_url; | 486 icon_url_ = it->icon_url; |
512 VLOG(1) << icon_url_; | 487 VLOG(1) << icon_url_; |
513 return; | 488 return; |
(...skipping 14 matching lines...) Expand all Loading... |
528 Destroy(FINAL_STATUS_HTTPS); | 503 Destroy(FINAL_STATUS_HTTPS); |
529 return false; | 504 return false; |
530 } | 505 } |
531 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && | 506 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && |
532 prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) { | 507 prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) { |
533 Destroy(FINAL_STATUS_RECENTLY_VISITED); | 508 Destroy(FINAL_STATUS_RECENTLY_VISITED); |
534 return false; | 509 return false; |
535 } | 510 } |
536 | 511 |
537 alias_urls_.push_back(url); | 512 alias_urls_.push_back(url); |
538 InformRenderProcessAboutPrerender(url, true, creator_child_id_); | 513 NotifyPrerenderAddAlias(url); |
539 return true; | 514 return true; |
540 } | 515 } |
541 | 516 |
542 bool PrerenderContents::Matches( | 517 bool PrerenderContents::Matches( |
543 const GURL& url, | 518 const GURL& url, |
544 const SessionStorageNamespace* session_storage_namespace) const { | 519 const SessionStorageNamespace* session_storage_namespace) const { |
545 DCHECK(child_id_ == -1 || session_storage_namespace); | 520 DCHECK(child_id_ == -1 || session_storage_namespace); |
546 if (session_storage_namespace && | 521 if (session_storage_namespace && |
547 session_storage_namespace_id_ != session_storage_namespace->id()) | 522 session_storage_namespace_id_ != session_storage_namespace->id()) |
548 return false; | 523 return false; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 677 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
703 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 678 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) |
704 return false; | 679 return false; |
705 const WebContents* web_contents = prerender_contents_->web_contents(); | 680 const WebContents* web_contents = prerender_contents_->web_contents(); |
706 return (web_contents->GetSiteInstance() != | 681 return (web_contents->GetSiteInstance() != |
707 web_contents->GetPendingSiteInstance()); | 682 web_contents->GetPendingSiteInstance()); |
708 } | 683 } |
709 | 684 |
710 | 685 |
711 } // namespace prerender | 686 } // namespace prerender |
OLD | NEW |