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_view_host.h" | 29 #include "content/public/browser/render_view_host.h" |
30 #include "content/public/browser/resource_request_details.h" | 30 #include "content/public/browser/resource_request_details.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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return AddAliasURL(prerender_url_); | 243 return AddAliasURL(prerender_url_); |
270 } | 244 } |
271 | 245 |
272 // static | 246 // static |
273 PrerenderContents::Factory* PrerenderContents::CreateFactory() { | 247 PrerenderContents::Factory* PrerenderContents::CreateFactory() { |
274 return new PrerenderContentsFactoryImpl(); | 248 return new PrerenderContentsFactoryImpl(); |
275 } | 249 } |
276 | 250 |
277 void PrerenderContents::StartPrerendering( | 251 void PrerenderContents::StartPrerendering( |
278 int creator_child_id, | 252 int creator_child_id, |
| 253 int prerender_id, |
279 const gfx::Size& size, | 254 const gfx::Size& size, |
280 SessionStorageNamespace* session_storage_namespace, | 255 SessionStorageNamespace* session_storage_namespace, |
281 bool is_control_group) { | 256 bool is_control_group) { |
282 DCHECK(profile_ != NULL); | 257 DCHECK(profile_ != NULL); |
283 DCHECK(!size.IsEmpty()); | 258 DCHECK(!size.IsEmpty()); |
284 DCHECK(!prerendering_has_started_); | 259 DCHECK(!prerendering_has_started_); |
285 DCHECK(prerender_contents_.get() == NULL); | 260 DCHECK(prerender_contents_.get() == NULL); |
286 DCHECK_EQ(-1, creator_child_id_); | 261 DCHECK_EQ(-1, creator_child_id_); |
287 DCHECK(size_.IsEmpty()); | 262 DCHECK(size_.IsEmpty()); |
288 DCHECK_EQ(1U, alias_urls_.size()); | 263 DCHECK_EQ(1U, alias_urls_.size()); |
289 | 264 |
290 creator_child_id_ = creator_child_id; | 265 creator_child_id_ = creator_child_id; |
| 266 prerender_id_ = prerender_id; |
291 session_storage_namespace_id_ = session_storage_namespace->id(); | 267 session_storage_namespace_id_ = session_storage_namespace->id(); |
292 size_ = size; | 268 size_ = size; |
293 | 269 |
294 InformRenderProcessAboutPrerender(prerender_url_, true, | 270 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
295 creator_child_id_); | 271 host->Send(new PrerenderMsg_StartedPrerender(prerender_id_)); |
296 | 272 |
297 DCHECK(load_start_time_.is_null()); | 273 DCHECK(load_start_time_.is_null()); |
298 load_start_time_ = base::TimeTicks::Now(); | 274 load_start_time_ = base::TimeTicks::Now(); |
299 | 275 |
300 // Everything after this point sets up the WebContents object and associated | 276 // Everything after this point sets up the WebContents object and associated |
301 // RenderView for the prerender page. Don't do this for members of the | 277 // RenderView for the prerender page. Don't do this for members of the |
302 // control group. | 278 // control group. |
303 if (is_control_group) | 279 if (is_control_group) |
304 return; | 280 return; |
305 | 281 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 } | 360 } |
385 | 361 |
386 void PrerenderContents::set_final_status(FinalStatus final_status) { | 362 void PrerenderContents::set_final_status(FinalStatus final_status) { |
387 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); | 363 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); |
388 DCHECK(final_status_ == FINAL_STATUS_MAX); | 364 DCHECK(final_status_ == FINAL_STATUS_MAX); |
389 | 365 |
390 final_status_ = final_status; | 366 final_status_ = final_status; |
391 } | 367 } |
392 | 368 |
393 PrerenderContents::~PrerenderContents() { | 369 PrerenderContents::~PrerenderContents() { |
394 DCHECK(final_status_ != FINAL_STATUS_MAX); | 370 DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
395 DCHECK(prerendering_has_been_cancelled_ || | 371 DCHECK( |
396 final_status_ == FINAL_STATUS_USED); | 372 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED); |
397 DCHECK(origin_ != ORIGIN_MAX); | 373 DCHECK_NE(ORIGIN_MAX, origin_); |
398 | 374 |
399 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( | 375 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( |
400 origin_, | 376 origin_, experiment_id_, match_complete_status_, final_status_); |
401 experiment_id_, | |
402 match_complete_status_, | |
403 final_status_); | |
404 | 377 |
405 if (child_id_ != -1 && route_id_ != -1) { | 378 if (child_id_ != -1 && route_id_ != -1) { |
406 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); | 379 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); |
407 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); | 380 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
408 it != alias_urls_.end(); | 381 host->Send(new PrerenderMsg_StoppedPrerender(prerender_id_)); |
409 ++it) { | |
410 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); | |
411 } | |
412 } | 382 } |
413 | 383 |
414 // If we still have a WebContents, clean up anything we need to and then | 384 // If we still have a WebContents, clean up anything we need to and then |
415 // destroy it. | 385 // destroy it. |
416 if (prerender_contents_.get()) | 386 if (prerender_contents_.get()) |
417 delete ReleasePrerenderContents(); | 387 delete ReleasePrerenderContents(); |
418 } | 388 } |
419 | 389 |
420 void PrerenderContents::Observe(int type, | 390 void PrerenderContents::Observe(int type, |
421 const content::NotificationSource& source, | 391 const content::NotificationSource& source, |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 Destroy(FINAL_STATUS_HTTPS); | 494 Destroy(FINAL_STATUS_HTTPS); |
525 return false; | 495 return false; |
526 } | 496 } |
527 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && | 497 if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && |
528 prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) { | 498 prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) { |
529 Destroy(FINAL_STATUS_RECENTLY_VISITED); | 499 Destroy(FINAL_STATUS_RECENTLY_VISITED); |
530 return false; | 500 return false; |
531 } | 501 } |
532 | 502 |
533 alias_urls_.push_back(url); | 503 alias_urls_.push_back(url); |
534 InformRenderProcessAboutPrerender(url, true, creator_child_id_); | 504 if (RenderProcessHost* host = RenderProcessHost::FromID(creator_child_id_)) |
| 505 host->Send(new PrerenderMsg_AddAliasToPrerender(prerender_id_, url)); |
535 return true; | 506 return true; |
536 } | 507 } |
537 | 508 |
538 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( | 509 void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( |
539 PrerenderContents* other_pc) { | 510 PrerenderContents* other_pc) { |
540 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin(); | 511 for (std::vector<GURL>::const_iterator it = other_pc->alias_urls_.begin(); |
541 it != other_pc->alias_urls_.end(); | 512 it != other_pc->alias_urls_.end(); |
542 ++it) { | 513 ++it) { |
543 alias_urls_.push_back(*it); | 514 alias_urls_.push_back(*it); |
544 } | 515 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 679 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
709 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 680 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) |
710 return false; | 681 return false; |
711 const WebContents* web_contents = prerender_contents_->web_contents(); | 682 const WebContents* web_contents = prerender_contents_->web_contents(); |
712 return (web_contents->GetSiteInstance() != | 683 return (web_contents->GetSiteInstance() != |
713 web_contents->GetPendingSiteInstance()); | 684 web_contents->GetPendingSiteInstance()); |
714 } | 685 } |
715 | 686 |
716 | 687 |
717 } // namespace prerender | 688 } // namespace prerender |
OLD | NEW |