Chromium Code Reviews| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 else | 66 else |
| 67 message = new PrerenderMsg_RemovePrerenderURL(url); | 67 message = new PrerenderMsg_RemovePrerenderURL(url); |
| 68 render_process_host->Send(message); | 68 render_process_host->Send(message); |
| 69 } | 69 } |
| 70 | 70 |
| 71 } // namespace | 71 } // namespace |
| 72 | 72 |
| 73 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { | 73 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { |
| 74 public: | 74 public: |
| 75 virtual PrerenderContents* CreatePrerenderContents( | 75 virtual PrerenderContents* CreatePrerenderContents( |
| 76 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, | 76 PrerenderManager* prerender_manager, Profile* profile, |
| 77 Profile* profile, const GURL& url, const content::Referrer& referrer, | 77 const GURL& url, const content::Referrer& referrer, |
| 78 Origin origin, uint8 experiment_id) OVERRIDE { | 78 Origin origin, uint8 experiment_id) OVERRIDE { |
| 79 return new PrerenderContents(prerender_manager, prerender_tracker, profile, | 79 return new PrerenderContents(prerender_manager, profile, |
| 80 url, referrer, origin, experiment_id); | 80 url, referrer, origin, experiment_id); |
| 81 } | 81 } |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // TabContentsDelegateImpl ----------------------------------------------------- | 84 // TabContentsDelegateImpl ----------------------------------------------------- |
| 85 | 85 |
| 86 class PrerenderContents::TabContentsDelegateImpl | 86 class PrerenderContents::TabContentsDelegateImpl |
| 87 : public content::WebContentsDelegate { | 87 : public content::WebContentsDelegate { |
| 88 public: | 88 public: |
| 89 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : | 89 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 bool user_gesture) OVERRIDE { | 160 bool user_gesture) OVERRIDE { |
| 161 // TODO(mmenke): Consider supporting this if it is a common case during | 161 // TODO(mmenke): Consider supporting this if it is a common case during |
| 162 // prerenders. | 162 // prerenders. |
| 163 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); | 163 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); |
| 164 } | 164 } |
| 165 | 165 |
| 166 private: | 166 private: |
| 167 PrerenderContents* prerender_contents_; | 167 PrerenderContents* prerender_contents_; |
| 168 }; | 168 }; |
| 169 | 169 |
| 170 PrerenderContents::Observer::Observer() { | |
| 171 } | |
| 172 | |
| 173 PrerenderContents::Observer::~Observer() { | |
| 174 } | |
| 175 | |
| 170 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( | 176 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( |
| 171 base::WeakPtr<PrerenderHandle> weak_prerender_handle, | 177 base::WeakPtr<PrerenderHandle> weak_prerender_handle, |
| 172 Origin origin, | 178 Origin origin, |
| 173 const GURL& url, | 179 const GURL& url, |
| 174 const content::Referrer& referrer, | 180 const content::Referrer& referrer, |
| 175 const gfx::Size& size) : weak_prerender_handle(weak_prerender_handle), | 181 const gfx::Size& size) : weak_prerender_handle(weak_prerender_handle), |
| 176 origin(origin), | 182 origin(origin), |
| 177 url(url), | 183 url(url), |
| 178 referrer(referrer), | 184 referrer(referrer), |
| 179 size(size) { | 185 size(size) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 195 prerender_contents_->web_contents()->GetController() | 201 prerender_contents_->web_contents()->GetController() |
| 196 .GetDefaultSessionStorageNamespace(); | 202 .GetDefaultSessionStorageNamespace(); |
| 197 } | 203 } |
| 198 prerender_manager_->StartPendingPrerenders( | 204 prerender_manager_->StartPendingPrerenders( |
| 199 child_id_, &pending_prerenders_, session_storage_namespace); | 205 child_id_, &pending_prerenders_, session_storage_namespace); |
| 200 pending_prerenders_.clear(); | 206 pending_prerenders_.clear(); |
| 201 } | 207 } |
| 202 | 208 |
| 203 PrerenderContents::PrerenderContents( | 209 PrerenderContents::PrerenderContents( |
| 204 PrerenderManager* prerender_manager, | 210 PrerenderManager* prerender_manager, |
| 205 PrerenderTracker* prerender_tracker, | |
| 206 Profile* profile, | 211 Profile* profile, |
| 207 const GURL& url, | 212 const GURL& url, |
| 208 const content::Referrer& referrer, | 213 const content::Referrer& referrer, |
| 209 Origin origin, | 214 Origin origin, |
| 210 uint8 experiment_id) | 215 uint8 experiment_id) |
| 211 : prerendering_has_started_(false), | 216 : prerendering_has_started_(false), |
| 212 prerender_manager_(prerender_manager), | 217 prerender_manager_(prerender_manager), |
| 213 prerender_tracker_(prerender_tracker), | |
| 214 prerender_url_(url), | 218 prerender_url_(url), |
| 215 referrer_(referrer), | 219 referrer_(referrer), |
| 216 profile_(profile), | 220 profile_(profile), |
| 217 page_id_(0), | 221 page_id_(0), |
| 218 session_storage_namespace_id_(-1), | 222 session_storage_namespace_id_(-1), |
| 219 has_stopped_loading_(false), | 223 has_stopped_loading_(false), |
| 220 has_finished_loading_(false), | 224 has_finished_loading_(false), |
| 221 final_status_(FINAL_STATUS_MAX), | 225 final_status_(FINAL_STATUS_MAX), |
| 222 match_complete_status_(MATCH_COMPLETE_DEFAULT), | 226 match_complete_status_(MATCH_COMPLETE_DEFAULT), |
| 223 prerendering_has_been_cancelled_(false), | 227 prerendering_has_been_cancelled_(false), |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 render_view_host_observer_.reset( | 307 render_view_host_observer_.reset( |
| 304 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); | 308 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); |
| 305 | 309 |
| 306 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); | 310 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); |
| 307 route_id_ = GetRenderViewHost()->GetRoutingID(); | 311 route_id_ = GetRenderViewHost()->GetRoutingID(); |
| 308 | 312 |
| 309 // Register this with the ResourceDispatcherHost as a prerender | 313 // Register this with the ResourceDispatcherHost as a prerender |
| 310 // RenderViewHost. This must be done before the Navigate message to catch all | 314 // RenderViewHost. This must be done before the Navigate message to catch all |
| 311 // resource requests, but as it is on the same thread as the Navigate message | 315 // resource requests, but as it is on the same thread as the Navigate message |
| 312 // (IO) there is no race condition. | 316 // (IO) there is no race condition. |
| 313 prerender_tracker_->OnPrerenderingStarted( | 317 NotifyPrerenderStart(); |
|
mmenke
2012/12/03 20:02:47
IMPORTANT: We do want to call this for the contro
gavinp
2012/12/04 18:04:48
It's the other way, I think. We don't want to tell
| |
| 314 child_id_, | |
| 315 route_id_, | |
| 316 prerender_manager_); | |
| 317 | 318 |
| 318 // Close ourselves when the application is shutting down. | 319 // Close ourselves when the application is shutting down. |
| 319 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 320 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 320 content::NotificationService::AllSources()); | 321 content::NotificationService::AllSources()); |
| 321 | 322 |
| 322 // Register for our parent profile to shutdown, so we can shut ourselves down | 323 // Register for our parent profile to shutdown, so we can shut ourselves down |
| 323 // as well (should only be called for OTR profiles, as we should receive | 324 // as well (should only be called for OTR profiles, as we should receive |
| 324 // APP_TERMINATING before non-OTR profiles are destroyed). | 325 // APP_TERMINATING before non-OTR profiles are destroyed). |
| 325 // TODO(tburkard): figure out if this is needed. | 326 // TODO(tburkard): figure out if this is needed. |
| 326 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 327 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 DCHECK_GE(route_id_, -1); | 365 DCHECK_GE(route_id_, -1); |
| 365 *route_id = route_id_; | 366 *route_id = route_id_; |
| 366 return route_id_ != -1; | 367 return route_id_ != -1; |
| 367 } | 368 } |
| 368 | 369 |
| 369 void PrerenderContents::set_final_status(FinalStatus final_status) { | 370 void PrerenderContents::set_final_status(FinalStatus final_status) { |
| 370 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); | 371 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); |
| 371 DCHECK(final_status_ == FINAL_STATUS_MAX); | 372 DCHECK(final_status_ == FINAL_STATUS_MAX); |
| 372 | 373 |
| 373 final_status_ = final_status; | 374 final_status_ = final_status; |
| 375 | |
| 376 NotifyPrerenderStop(); | |
| 374 } | 377 } |
| 375 | 378 |
| 376 PrerenderContents::~PrerenderContents() { | 379 PrerenderContents::~PrerenderContents() { |
| 377 DCHECK(final_status_ != FINAL_STATUS_MAX); | 380 DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
| 378 DCHECK(prerendering_has_been_cancelled_ || | 381 DCHECK( |
| 379 final_status_ == FINAL_STATUS_USED); | 382 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED); |
| 380 DCHECK(origin_ != ORIGIN_MAX); | 383 DCHECK_NE(ORIGIN_MAX, origin_); |
| 381 | 384 |
| 382 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( | 385 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( |
| 383 origin_, | 386 origin_, experiment_id_, match_complete_status_, final_status_); |
| 384 experiment_id_, | |
| 385 match_complete_status_, | |
| 386 final_status_); | |
| 387 | 387 |
| 388 if (child_id_ != -1 && route_id_ != -1) { | 388 if (child_id_ != -1 && route_id_ != -1) { |
| 389 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_); | |
| 390 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); | 389 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); |
| 391 it != alias_urls_.end(); | 390 it != alias_urls_.end(); |
| 392 ++it) { | 391 ++it) { |
| 393 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); | 392 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); |
| 394 } | 393 } |
| 395 } | 394 } |
| 396 | 395 |
| 397 // If we still have a WebContents, clean up anything we need to and then | 396 // If we still have a WebContents, clean up anything we need to and then |
| 398 // destroy it. | 397 // destroy it. |
| 399 if (prerender_contents_.get()) | 398 if (prerender_contents_.get()) |
| 400 delete ReleasePrerenderContents(); | 399 delete ReleasePrerenderContents(); |
| 401 } | 400 } |
| 402 | 401 |
| 402 void PrerenderContents::AddObserver(Observer* observer) { | |
| 403 observer_list_.AddObserver(observer); | |
| 404 } | |
| 405 | |
| 406 void PrerenderContents::RemoveObserver(Observer* observer) { | |
| 407 observer_list_.RemoveObserver(observer); | |
| 408 } | |
| 409 | |
| 403 void PrerenderContents::Observe(int type, | 410 void PrerenderContents::Observe(int type, |
| 404 const content::NotificationSource& source, | 411 const content::NotificationSource& source, |
| 405 const content::NotificationDetails& details) { | 412 const content::NotificationDetails& details) { |
| 406 switch (type) { | 413 switch (type) { |
| 407 case chrome::NOTIFICATION_PROFILE_DESTROYED: | 414 case chrome::NOTIFICATION_PROFILE_DESTROYED: |
| 408 Destroy(FINAL_STATUS_PROFILE_DESTROYED); | 415 Destroy(FINAL_STATUS_PROFILE_DESTROYED); |
| 409 return; | 416 return; |
| 410 | 417 |
| 411 case chrome::NOTIFICATION_APP_TERMINATING: | 418 case chrome::NOTIFICATION_APP_TERMINATING: |
| 412 Destroy(FINAL_STATUS_APP_TERMINATING); | 419 Destroy(FINAL_STATUS_APP_TERMINATING); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 WebContents* PrerenderContents::CreateWebContents( | 484 WebContents* PrerenderContents::CreateWebContents( |
| 478 SessionStorageNamespace* session_storage_namespace) { | 485 SessionStorageNamespace* session_storage_namespace) { |
| 479 // TODO(ajwong): Remove the temporary map once prerendering is aware of | 486 // TODO(ajwong): Remove the temporary map once prerendering is aware of |
| 480 // multiple session storage namespaces per tab. | 487 // multiple session storage namespaces per tab. |
| 481 content::SessionStorageNamespaceMap session_storage_namespace_map; | 488 content::SessionStorageNamespaceMap session_storage_namespace_map; |
| 482 session_storage_namespace_map[""] = session_storage_namespace; | 489 session_storage_namespace_map[""] = session_storage_namespace; |
| 483 return WebContents::CreateWithSessionStorage( | 490 return WebContents::CreateWithSessionStorage( |
| 484 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace_map); | 491 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace_map); |
| 485 } | 492 } |
| 486 | 493 |
| 494 void PrerenderContents::NotifyPrerenderStart() { | |
| 495 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStart(this)); | |
| 496 } | |
| 497 | |
| 498 void PrerenderContents::NotifyPrerenderStop() { | |
| 499 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStop(this)); | |
| 500 } | |
| 501 | |
| 487 void PrerenderContents::OnUpdateFaviconURL( | 502 void PrerenderContents::OnUpdateFaviconURL( |
| 488 int32 page_id, | 503 int32 page_id, |
| 489 const std::vector<FaviconURL>& urls) { | 504 const std::vector<FaviconURL>& urls) { |
| 490 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; | 505 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; |
| 491 for (std::vector<FaviconURL>::const_iterator it = urls.begin(); | 506 for (std::vector<FaviconURL>::const_iterator it = urls.begin(); |
| 492 it != urls.end(); ++it) { | 507 it != urls.end(); ++it) { |
| 493 if (it->icon_type == FaviconURL::FAVICON) { | 508 if (it->icon_type == FaviconURL::FAVICON) { |
| 494 icon_url_ = it->icon_url; | 509 icon_url_ = it->icon_url; |
| 495 VLOG(1) << icon_url_; | 510 VLOG(1) << icon_url_; |
| 496 return; | 511 return; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 | 588 |
| 574 void PrerenderContents::Destroy(FinalStatus final_status) { | 589 void PrerenderContents::Destroy(FinalStatus final_status) { |
| 575 if (prerendering_has_been_cancelled_) | 590 if (prerendering_has_been_cancelled_) |
| 576 return; | 591 return; |
| 577 | 592 |
| 578 if (child_id_ != -1 && route_id_ != -1) { | 593 if (child_id_ != -1 && route_id_ != -1) { |
| 579 // Cancel the prerender in the PrerenderTracker. This is needed | 594 // Cancel the prerender in the PrerenderTracker. This is needed |
| 580 // because destroy may be called directly from the UI thread without calling | 595 // because destroy may be called directly from the UI thread without calling |
| 581 // TryCancel(). This is difficult to completely avoid, since prerendering | 596 // TryCancel(). This is difficult to completely avoid, since prerendering |
| 582 // can be cancelled before a RenderView is created. | 597 // can be cancelled before a RenderView is created. |
| 583 bool is_cancelled = prerender_tracker_->TryCancel( | 598 bool is_cancelled = prerender_manager()->prerender_tracker()->TryCancel( |
| 584 child_id_, route_id_, final_status); | 599 child_id_, route_id_, final_status); |
| 585 CHECK(is_cancelled); | 600 CHECK(is_cancelled); |
| 586 | 601 |
| 587 // A different final status may have been set already from another thread. | 602 // A different final status may have been set already from another thread. |
| 588 // If so, use it instead. | 603 // If so, use it instead. |
| 589 if (!prerender_tracker_->GetFinalStatus(child_id_, route_id_, | 604 if (!prerender_manager()->prerender_tracker()-> |
| 590 &final_status)) { | 605 GetFinalStatus(child_id_, route_id_, &final_status)) { |
| 591 NOTREACHED(); | 606 NOTREACHED(); |
| 592 } | 607 } |
| 593 } | 608 } |
| 594 set_final_status(final_status); | 609 set_final_status(final_status); |
| 595 | 610 |
| 596 prerendering_has_been_cancelled_ = true; | 611 prerendering_has_been_cancelled_ = true; |
| 597 prerender_manager_->AddToHistory(this); | 612 prerender_manager_->AddToHistory(this); |
| 598 prerender_manager_->MoveEntryToPendingDelete(this, final_status); | 613 prerender_manager_->MoveEntryToPendingDelete(this, final_status); |
| 599 | 614 |
| 600 // We may destroy the PrerenderContents before we have initialized the | 615 // We may destroy the PrerenderContents before we have initialized the |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 685 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 700 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
| 686 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) | 701 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) |
| 687 return false; | 702 return false; |
| 688 const WebContents* web_contents = prerender_contents_->web_contents(); | 703 const WebContents* web_contents = prerender_contents_->web_contents(); |
| 689 return (web_contents->GetSiteInstance() != | 704 return (web_contents->GetSiteInstance() != |
| 690 web_contents->GetPendingSiteInstance()); | 705 web_contents->GetPendingSiteInstance()); |
| 691 } | 706 } |
| 692 | 707 |
| 693 | 708 |
| 694 } // namespace prerender | 709 } // namespace prerender |
| OLD | NEW |