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 |