diff options
5 files changed, 30 insertions, 67 deletions
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h index 7b24ea6..968ba9d 100644 --- a/chrome/browser/prerender/prerender_final_status.h +++ b/chrome/browser/prerender/prerender_final_status.h @@ -27,7 +27,7 @@ enum FinalStatus { FINAL_STATUS_RENDERER_UNRESPONSIVE, FINAL_STATUS_TOO_MANY_PROCESSES, FINAL_STATUS_RATE_LIMIT_EXCEEDED, - FINAL_STATUS_PENDING_SKIPPED, + FINAL_STATUS_PENDING_SKIPPED, // Obsolete. FINAL_STATUS_CONTROL_GROUP, FINAL_STATUS_HTML5_MEDIA, FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED, diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index abf7e75..0aef77d 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc @@ -173,8 +173,7 @@ void HandleTag( int render_process_id, int render_view_id, const GURL& url, - const GURL& referrer, - bool make_pending) { + const GURL& referrer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); if (!prerender_manager || !prerender_manager->is_enabled()) @@ -183,13 +182,8 @@ void HandleTag( std::pair<int, int> child_route_id_pair = std::make_pair(render_process_id, render_view_id); - // TODO(cbentzel): Should the decision to make pending be done on the - // UI thread rather than the IO thread? The page may have - // become activated at this point. - if (make_pending) - prerender_manager->AddPendingPreload(child_route_id_pair, url, referrer); - else - prerender_manager->AddPreload(child_route_id_pair, url, referrer); + + prerender_manager->AddPreload(child_route_id_pair, url, referrer); } void DestroyPreloadForRenderView( @@ -248,6 +242,14 @@ bool PrerenderManager::AddPreload( const GURL& url_arg, const GURL& referrer) { DCHECK(CalledOnValidThread()); + + // If the referring page is prerendering, defer the prerender. + if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != + prerender_list_.end()) { + AddPendingPreload(child_route_id_pair, url_arg, referrer); + return true; + } + DeleteOldEntries(); DeletePendingDeleteEntries(); @@ -327,23 +329,8 @@ void PrerenderManager::AddPendingPreload( const std::pair<int, int>& child_route_id_pair, const GURL& url, const GURL& referrer) { - DCHECK(CalledOnValidThread()); - // Check if this is coming from a valid prerender RenderViewHost. - bool is_valid_prerender = - (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != - prerender_list_.end()); - - // If not, we could check to see if the RenderViewHost specified by the - // child_route_id_pair exists and if so just start prerendering, as this - // suggests that the link was clicked, though this might prerender something - // that the user has already navigated away from. For now, we'll be - // conservative and skip the prerender which will mean some prerender requests - // from prerendered pages will be missed if the user navigates quickly. - if (!is_valid_prerender) { - RecordFinalStatus(FINAL_STATUS_PENDING_SKIPPED); - return; - } - + DCHECK(FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != + prerender_list_.end()); PendingPrerenderList::iterator it = pending_prerender_list_.find(child_route_id_pair); if (it == pending_prerender_list_.end()) { diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index cd039b6..e6f974a 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h @@ -47,8 +47,7 @@ void HandleTag( int render_process_id, int render_view_id, const GURL& url, - const GURL& referrer, - bool make_pending); + const GURL& referrer); void DestroyPreloadForRenderView( const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, @@ -81,15 +80,13 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, // RenderViewHost that the prerender request came from and is used to // set the initial window size of the RenderViewHost used for prerendering. // Returns true if the URL was added, false if it was not. + // If |child_route_id_pair| itself is prerendering, adds the preloads as + // a pending preload. bool AddPreload( const std::pair<int, int>& child_route_id_pair, const GURL& url, const GURL& referrer); - void AddPendingPreload(const std::pair<int, int>& child_route_id_pair, - const GURL& url, - const GURL& referrer); - // Destroy all preloads for the given child route id pair and assign a final // status to them. virtual void DestroyPreloadForChildRouteIdPair( @@ -211,6 +208,13 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, struct PrerenderContentsData; struct NavigationRecord; + // Adds a pending preload issued by the prerendering RenderView identified by + // |child_route_id_pair|. If and when that prerendering RenderView is used, + // the specified prerender will start. + void AddPendingPreload(const std::pair<int, int>& child_route_id_pair, + const GURL& url, + const GURL& referrer); + // Starts scheduling periodic cleanups. void StartSchedulingPeriodicCleanups(); // Stops scheduling periodic cleanups if they're no longer needed. diff --git a/chrome/browser/prerender/prerender_manager_unittest.cc b/chrome/browser/prerender/prerender_manager_unittest.cc index c1a8973..9b82c16 100644 --- a/chrome/browser/prerender/prerender_manager_unittest.cc +++ b/chrome/browser/prerender/prerender_manager_unittest.cc @@ -421,41 +421,16 @@ TEST_F(PrerenderManagerTest, PendingPreloadTest) { GURL pending_url("http://news.google.com/"); - prerender_manager()->AddPendingPreload(std::make_pair(child_id, route_id), - pending_url, - url); + EXPECT_TRUE( + prerender_manager()->AddPreload(std::make_pair(child_id, route_id), + pending_url, + url)); EXPECT_TRUE(prerender_manager()->IsPendingEntry(pending_url)); EXPECT_TRUE(prerender_contents->has_started()); ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url)); } -TEST_F(PrerenderManagerTest, PendingPreloadSkippedTest) { - GURL url("http://www.google.com/"); - DummyPrerenderContents* prerender_contents = - prerender_manager()->CreateNextPrerenderContents( - url, - FINAL_STATUS_TIMED_OUT); - - int child_id; - int route_id; - ASSERT_TRUE(prerender_contents->GetChildId(&child_id)); - ASSERT_TRUE(prerender_contents->GetRouteId(&route_id)); - - EXPECT_TRUE(prerender_manager()->AddSimplePreload(url)); - prerender_manager()->AdvanceTime(prerender_manager()->max_prerender_age() - + base::TimeDelta::FromSeconds(1)); - // GetEntry will cull old entries which should now include prerender_contents. - ASSERT_EQ(NULL, prerender_manager()->GetEntry(url)); - - GURL pending_url("http://news.google.com/"); - - prerender_manager()->AddPendingPreload(std::make_pair(child_id, route_id), - pending_url, - url); - EXPECT_FALSE(prerender_manager()->IsPendingEntry(pending_url)); -} - // Ensure that extracting a urlencoded URL in the url= query string component // works. TEST_F(PrerenderManagerTest, ExtractURLInQueryStringTest) { diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc index 26e03b1..5168a49 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc @@ -26,8 +26,6 @@ bool ChromeResourceDispatcherHostObserver::ShouldBeginRequest( const content::ResourceContext& resource_context, const GURL& referrer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - bool is_prerendering = prerender_tracker_->IsPrerenderingOnIOThread( - child_id, route_id); // Handle a PREFETCH resource type. If prefetch is disabled, squelch the // request. Otherwise, do a normal request to warm the cache. @@ -51,15 +49,14 @@ bool ChromeResourceDispatcherHostObserver::ShouldBeginRequest( child_id, route_id, request_data.url, - referrer, - is_prerendering)); + referrer)); } // Prerendering or not, this request should be aborted. return false; } // Abort any prerenders that spawn requests that use invalid HTTP methods. - if (is_prerendering && + if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id) && !prerender::PrerenderManager::IsValidHttpMethod(request_data.method)) { prerender_tracker_->TryCancelOnIOThread( child_id, route_id, |