Chromium Code Reviews| Index: chrome/browser/prerender/prerender_contents.cc |
| diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc |
| index ce7e59a57cf90a326ec9e6cce4995d3d7951a01e..df3bd191e90b0029c875305967a54e036f38c4a8 100644 |
| --- a/chrome/browser/prerender/prerender_contents.cc |
| +++ b/chrome/browser/prerender/prerender_contents.cc |
| @@ -43,23 +43,47 @@ namespace prerender { |
| namespace { |
| -// Compares URLs ignoring any ref for the purposes of matching URLs when |
| -// prerendering. |
| -struct PrerenderURLPredicate { |
| - explicit PrerenderURLPredicate(const GURL& url) |
| - : url_(url) { |
| - } |
| +// A prerender handle that embeds another prerender and acts as a pass-through. |
| +class PendingPrerender : public PrerenderHandleInterface { |
|
dominich
2012/06/18 15:32:44
I think you're conflating two things here. There's
gavinp
2012/06/18 16:40:48
This class is gone in the next upload. The questio
|
| + public: |
| + PendingPrerender(); |
| - bool operator()(const GURL& url) const { |
| - return url.scheme() == url_.scheme() && |
| - url.host() == url_.host() && |
| - url.port() == url_.port() && |
| - url.path() == url_.path() && |
| - url.query() == url_.query(); |
| - } |
| - GURL url_; |
| + bool is_destroyed() const { return is_destroyed_; } |
| + void set_prerender(PrerenderHandle prerender) { prerender_ = prerender; } |
| + |
| + virtual bool DidFinishLoading() const OVERRIDE; |
| + virtual bool IsPending() const OVERRIDE; |
| + |
| + private: |
| + virtual ~PendingPrerender() OVERRIDE; |
| + virtual void Destroy() OVERRIDE; |
| + |
| + bool is_destroyed_; |
| + PrerenderHandle prerender_; |
| }; |
| +PendingPrerender::PendingPrerender() : is_destroyed_(false) { } |
| + |
| +bool PendingPrerender::DidFinishLoading() const { |
| + if (!prerender_) |
| + return false; |
| + return prerender_->DidFinishLoading(); |
| +} |
| + |
| +bool PendingPrerender::IsPending() const { |
| + if (!prerender_) |
| + return true; |
| + return prerender_->IsPending(); |
| +} |
| + |
| +PendingPrerender::~PendingPrerender() { |
| + Destroy(); |
| +} |
| + |
| +void PendingPrerender::Destroy() { |
| + is_destroyed_ = true; |
| +} |
| + |
| // Tells the render process at |child_id| whether |url| is a new prerendered |
| // page, or whether |url| is being removed as a prerendered page. Currently |
| // this will only inform the render process that created the prerendered page |
| @@ -97,19 +121,23 @@ class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { |
| }; |
| struct PrerenderContents::PendingPrerenderInfo { |
| - PendingPrerenderInfo(const GURL& url, |
| + PendingPrerenderInfo(scoped_refptr<PendingPrerender> prerender, |
| + const GURL& url, |
| const content::Referrer& referrer, |
| const gfx::Size& size); |
| + scoped_refptr<PendingPrerender> prerender; |
| const GURL url; |
| const content::Referrer referrer; |
| const gfx::Size size; |
| }; |
| PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( |
| + scoped_refptr<PendingPrerender> prerender, |
| const GURL& url, |
| const content::Referrer& referrer, |
| const gfx::Size& size) |
| - : url(url), |
| + : prerender(prerender), |
| + url(url), |
| referrer(referrer), |
| size(size) { |
| } |
| @@ -206,10 +234,14 @@ class PrerenderContents::TabContentsDelegateImpl |
| PrerenderContents* prerender_contents_; |
| }; |
| -void PrerenderContents::AddPendingPrerender(const GURL& url, |
| - const content::Referrer& referrer, |
| - const gfx::Size& size) { |
| - pending_prerender_list_.push_back(PendingPrerenderInfo(url, referrer, size)); |
| +PrerenderHandle PrerenderContents::AddPendingPrerender( |
| + const GURL& url, |
| + const content::Referrer& referrer, |
| + const gfx::Size& size) { |
| + scoped_refptr<PendingPrerender> pending_prerender(new PendingPrerender); |
| + pending_prerender_list_.push_back( |
| + PendingPrerenderInfo(pending_prerender, url, referrer, size)); |
| + return pending_prerender; |
| } |
| bool PrerenderContents::IsPendingEntry(const GURL& url) const { |
| @@ -227,10 +259,11 @@ void PrerenderContents::StartPendingPrerenders() { |
| PendingPrerenderList pending_prerender_list; |
| pending_prerender_list.swap(pending_prerender_list_); |
| for (PendingPrerenderList::iterator it = pending_prerender_list.begin(); |
| - it != pending_prerender_list.end(); |
| - ++it) { |
| - prerender_manager_->AddPrerenderFromLinkRelPrerender( |
| - child_id_, route_id_, it->url, it->referrer, it->size); |
| + it != pending_prerender_list.end(); ++it) { |
| + if (it->prerender->is_destroyed()) continue; |
| + it->prerender->set_prerender( |
|
dominich
2012/06/18 15:32:44
Why don't we clear the list of pending prerenders
gavinp
2012/06/18 16:40:48
Also gone in the new approach.
|
| + prerender_manager_->AddPrerenderFromLinkRelPrerender( |
| + child_id_, route_id_, it->url, it->referrer, it->size)); |
| } |
| } |
| @@ -260,9 +293,12 @@ PrerenderContents::PrerenderContents( |
| experiment_id_(experiment_id), |
| creator_child_id_(-1) { |
| DCHECK(prerender_manager != NULL); |
| + DVLOG(2) << "PrerenderContents constructor\n"; |
| + DVLOG(3) << " url = " << url.spec(); |
| } |
| -bool PrerenderContents::Init() { |
| +bool PrerenderContents::Init(WeakPrerenderHandle prerender) { |
| + prerender_ = prerender; |
| return AddAliasURL(prerender_url_); |
| } |
| @@ -392,17 +428,20 @@ bool PrerenderContents::GetRouteId(int* route_id) const { |
| } |
| void PrerenderContents::set_final_status(FinalStatus final_status) { |
| - DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); |
| - DCHECK(final_status_ == FINAL_STATUS_MAX); |
| + DCHECK_LE(FINAL_STATUS_USED, final_status); |
| + DCHECK_GT(FINAL_STATUS_MAX, final_status); |
| + |
| + DCHECK_EQ(FINAL_STATUS_MAX, final_status_); |
| final_status_ = final_status; |
| } |
| PrerenderContents::~PrerenderContents() { |
| - DCHECK(final_status_ != FINAL_STATUS_MAX); |
| + DVLOG(4) << "PrerenderContents::~PrerenderContents()"; |
| + DCHECK_NE(FINAL_STATUS_MAX, final_status_); |
| DCHECK(prerendering_has_been_cancelled_ || |
| final_status_ == FINAL_STATUS_USED); |
| - DCHECK(origin_ != ORIGIN_MAX); |
| + DCHECK_NE(ORIGIN_MAX, origin_); |
| prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( |
| origin_, |
| @@ -548,17 +587,23 @@ void PrerenderContents::AddAliasURLsFromOtherPrerenderContents( |
| } |
| } |
| -bool PrerenderContents::MatchesURL(const GURL& url, GURL* matching_url) const { |
| - std::vector<GURL>::const_iterator matching_url_iterator = |
| - std::find_if(alias_urls_.begin(), |
| - alias_urls_.end(), |
| - PrerenderURLPredicate(url)); |
| - if (matching_url_iterator != alias_urls_.end()) { |
| - if (matching_url) |
| - *matching_url = *matching_url_iterator; |
| - return true; |
| +bool PrerenderContents::Matches( |
| + const GURL& url, |
| + const content::SessionStorageNamespace* session_storage_namespace) const { |
| + DVLOG(4) << "PrerenderContents::Matches"; |
| + if (child_id_ != -1) { |
| + RenderViewHost* render_view_host = |
| + RenderViewHost::FromID(child_id_, route_id_); |
| + if (!render_view_host || !render_view_host->GetView() || |
| + session_storage_namespace != |
| + render_view_host->GetSessionStorageNamespace()) { |
| + return false; |
| + } |
| } |
| - return false; |
| + DCHECK_LE(1, std::count(alias_urls_.begin(), alias_urls_.end(), url)); |
| + std::vector<GURL>::const_iterator it = std::find(alias_urls_.begin(), |
| + alias_urls_.end(), url); |
| + return it != alias_urls_.end(); |
| } |
| void PrerenderContents::OnJSOutOfMemory() { |
| @@ -634,7 +679,9 @@ void PrerenderContents::Destroy(FinalStatus final_status) { |
| prerendering_has_been_cancelled_ = true; |
| // This has to be done after setting the final status, as it adds the |
| // prerender to the history. |
| - prerender_manager_->MoveEntryToPendingDelete(this, final_status); |
| + if (prerendering_has_started_ && prerender_) { |
| + prerender_manager_->MoveEntryToPendingDelete(prerender_, final_status); |
| + } |
| // We may destroy the PrerenderContents before we have initialized the |
| // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to |
| @@ -722,5 +769,4 @@ bool PrerenderContents::IsCrossSiteNavigationPending() const { |
| web_contents->GetPendingSiteInstance()); |
| } |
| - |
| } // namespace prerender |