summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-14 15:20:42 +0000
committergavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-14 15:20:42 +0000
commit1c7fa0a26fed6f48fbb2a7fe5724c5f9143610ff (patch)
treeb88ecd45df859d7486de533bb5d6fa198dc1a4be
parent5463c700e47a3beac464d95b251335bd90145a4d (diff)
downloadchromium_src-1c7fa0a26fed6f48fbb2a7fe5724c5f9143610ff.zip
chromium_src-1c7fa0a26fed6f48fbb2a7fe5724c5f9143610ff.tar.gz
chromium_src-1c7fa0a26fed6f48fbb2a7fe5724c5f9143610ff.tar.bz2
Revert 146735 - Handle interface to prerenders.
It broke the windows aura build, which isn't on standard tries. The prerender_manager now returns a PrerenderHandle* when creating a prerender; this is a useful object for canceling the prerender, as well as signaling navigation, etc... BUG=None Review URL: https://chromiumcodereview.appspot.com/10553029 TBR=gavinp@chromium.org Review URL: https://chromiumcodereview.appspot.com/10783013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146736 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/predictors/autocomplete_action_predictor.cc19
-rw-r--r--chrome/browser/predictors/autocomplete_action_predictor.h24
-rw-r--r--chrome/browser/prerender/prerender_browsertest.cc140
-rw-r--r--chrome/browser/prerender/prerender_contents.cc135
-rw-r--r--chrome/browser/prerender/prerender_contents.h73
-rw-r--r--chrome/browser/prerender/prerender_final_status.h4
-rw-r--r--chrome/browser/prerender/prerender_handle.cc71
-rw-r--r--chrome/browser/prerender/prerender_handle.h79
-rw-r--r--chrome/browser/prerender/prerender_link_manager.cc68
-rw-r--r--chrome/browser/prerender/prerender_link_manager.h14
-rw-r--r--chrome/browser/prerender/prerender_manager.cc578
-rw-r--r--chrome/browser/prerender/prerender_manager.h212
-rw-r--r--chrome/browser/prerender/prerender_unittest.cc365
-rw-r--r--chrome/browser/ui/omnibox/omnibox_edit_model.cc15
-rw-r--r--chrome/chrome_browser.gypi2
15 files changed, 660 insertions, 1139 deletions
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 642bc7c..2ac67fa 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -26,7 +26,6 @@
#include "chrome/browser/predictors/predictor_database.h"
#include "chrome/browser/predictors/predictor_database_factory.h"
#include "chrome/browser/prerender/prerender_field_trial.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
@@ -120,8 +119,6 @@ AutocompleteActionPredictor::~AutocompleteActionPredictor() {
main_profile_predictor_->incognito_predictor_ = NULL;
else if (incognito_predictor_)
incognito_predictor_->main_profile_predictor_ = NULL;
- if (prerender_handle_.get())
- prerender_handle_->OnCancel();
}
void AutocompleteActionPredictor::RegisterTransitionalMatches(
@@ -156,22 +153,6 @@ void AutocompleteActionPredictor::ClearTransitionalMatches() {
transitional_matches_.clear();
}
-void AutocompleteActionPredictor::StartPrerendering(
- const GURL& url,
- content::SessionStorageNamespace* session_storage_namespace,
- const gfx::Size& size) {
- if (prerender_handle_.get())
- prerender_handle_->OnNavigateAway();
- if (prerender::PrerenderManager* prerender_manager =
- prerender::PrerenderManagerFactory::GetForProfile(profile_)) {
- prerender_handle_.reset(
- prerender_manager->AddPrerenderFromOmnibox(
- url, session_storage_namespace, size));
- } else {
- prerender_handle_.reset();
- }
-}
-
// Given a match, return a recommended action.
AutocompleteActionPredictor::Action
AutocompleteActionPredictor::RecommendAction(
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.h b/chrome/browser/predictors/autocomplete_action_predictor.h
index 34a725a..d78ced96 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.h
+++ b/chrome/browser/predictors/autocomplete_action_predictor.h
@@ -9,7 +9,6 @@
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/string16.h"
#include "chrome/browser/history/history_types.h"
@@ -26,22 +25,10 @@ class HistoryService;
class PredictorsHandler;
class Profile;
-namespace content {
-class SessionStorageNamespace;
-}
-
-namespace gfx {
-class Size;
-}
-
namespace history {
class URLDatabase;
}
-namespace prerender {
-class PrerenderHandle;
-}
-
namespace predictors {
// This class is responsible for determining the correct predictive network
@@ -91,15 +78,6 @@ class AutocompleteActionPredictor
Action RecommendAction(const string16& user_text,
const AutocompleteMatch& match) const;
- // Begin prerendering |url| with |session_storage_namespace|. The |size| gives
- // the initial size for the target prerender. The predictor will run at most
- // one prerender at a time, so launching a prerender will cancel our previous
- // prerenders (if any).
- void StartPrerendering(
- const GURL& url,
- content::SessionStorageNamespace* session_storage_namespace,
- const gfx::Size& size);
-
// Return true if the suggestion type warrants a TCP/IP preconnection.
// i.e., it is now quite likely that the user will select the related domain.
static bool IsPreconnectable(const AutocompleteMatch& match);
@@ -220,8 +198,6 @@ class AutocompleteActionPredictor
// This is cleared after every Omnibox navigation.
std::vector<TransitionalMatch> transitional_matches_;
- scoped_ptr<prerender::PrerenderHandle> prerender_handle_;
-
// This allows us to predict the effect of confidence threshold changes on
// accuracy. This is cleared after every omnibox navigation.
mutable std::vector<std::pair<GURL, double> > tracked_urls_;
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 89f278e..104dffc 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/favicon/favicon_tab_helper.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_contents.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_link_manager.h"
#include "chrome/browser/prerender/prerender_link_manager_factory.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -33,7 +32,6 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
@@ -48,7 +46,6 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
-#include "content/public/test/test_navigation_observer.h"
#include "grit/generated_resources.h"
#include "net/base/mock_host_resolver.h"
#include "net/url_request/url_request_context.h"
@@ -116,11 +113,13 @@ bool ShouldRenderPrerenderedPageCorrectly(FinalStatus status) {
case FINAL_STATUS_USED:
case FINAL_STATUS_WINDOW_OPENER:
case FINAL_STATUS_APP_TERMINATING:
+ case FINAL_STATUS_FRAGMENT_MISMATCH:
case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
// We'll crash the renderer after it's loaded.
case FINAL_STATUS_RENDERER_CRASHED:
case FINAL_STATUS_CANCELLED:
case FINAL_STATUS_DEVTOOLS_ATTACHED:
+ case FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH:
return true;
default:
return false;
@@ -230,15 +229,12 @@ class TestPrerenderContents : public PrerenderContents {
}
}
- virtual void AddPendingPrerender(
- base::WeakPtr<PrerenderHandle> weak_prerender_handle,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size) OVERRIDE {
- PrerenderContents::AddPendingPrerender(
- weak_prerender_handle, url, referrer, size);
+ virtual void AddPendingPrerender(const GURL& url,
+ const content::Referrer& referrer,
+ const gfx::Size& size) OVERRIDE {
+ PrerenderContents::AddPendingPrerender(url, referrer, size);
if (expected_pending_prerenders_ > 0 &&
- pending_prerenders().size() == expected_pending_prerenders_) {
+ pending_prerender_list()->size() == expected_pending_prerenders_) {
MessageLoop::current()->Quit();
}
}
@@ -264,28 +260,13 @@ class TestPrerenderContents : public PrerenderContents {
// Waits until the prerender has |expected_pending_prerenders| pending
// prerenders.
void WaitForPendingPrerenders(size_t expected_pending_prerenders) {
- if (pending_prerenders().size() < expected_pending_prerenders) {
+ if (pending_prerender_list()->size() < expected_pending_prerenders) {
expected_pending_prerenders_ = expected_pending_prerenders;
ui_test_utils::RunMessageLoop();
expected_pending_prerenders_ = 0;
}
- EXPECT_EQ(expected_pending_prerenders, pending_prerenders().size());
- }
-
- bool UrlIsPending(const GURL& url) const {
- for (std::vector<PendingPrerenderInfo>::const_iterator
- it = pending_prerenders().begin(),
- end = pending_prerenders().end();
- it != end;
- ++it) {
- if (it->url == url && it->weak_prerender_handle) {
- EXPECT_TRUE(IsPendingEntry(*it->weak_prerender_handle));
- EXPECT_TRUE(it->weak_prerender_handle->IsPending());
- return true;
- }
- }
- return false;
+ EXPECT_EQ(expected_pending_prerenders, pending_prerender_list()->size());
}
// For tests that open the prerender in a new background tab, the RenderView
@@ -295,12 +276,6 @@ class TestPrerenderContents : public PrerenderContents {
int number_of_loads() const { return number_of_loads_; }
- FinalStatus expected_final_status() const { return expected_final_status_; }
-
- bool quit_message_loop_on_destruction() const {
- return quit_message_loop_on_destruction_;
- }
-
private:
virtual void OnRenderViewHostCreated(
RenderViewHost* new_render_view_host) OVERRIDE {
@@ -517,15 +492,6 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
virtual ~PrerenderBrowserTest() {}
- content::SessionStorageNamespace* GetSessionStorageNamespace() const {
- TabContents* tab_contents =
- current_browser()->tab_strip_model()->GetActiveTabContents();
- if (!tab_contents)
- return NULL;
- return tab_contents->web_contents()->GetRenderViewHost()->
- GetSessionStorageNamespace();
- }
-
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
#if defined(ENABLE_SAFE_BROWSING)
SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
@@ -739,21 +705,17 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
}
bool UrlIsInPrerenderManager(const std::string& html_file) const {
- return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
+ GURL dest_url = test_server()->GetURL(html_file);
+ return (GetPrerenderManager()->FindEntry(dest_url) != NULL);
}
- bool UrlIsInPrerenderManager(const GURL& url) const {
- return GetPrerenderManager()->FindPrerenderData(
- url, GetSessionStorageNamespace()) != NULL;
+ bool UrlIsInPrerenderManager(const GURL& url) {
+ return (GetPrerenderManager()->FindEntry(url) != NULL);
}
- // This only checks to see if the URL is pending in our TestPrerenderContents.
- bool UrlIsPending(const std::string& html_file) const {
- TestPrerenderContents* test_prerender_contents = GetPrerenderContents();
- if (!test_prerender_contents)
- return false;
+ bool UrlIsPendingInPrerenderManager(const std::string& html_file) const {
GURL dest_url = test_server()->GetURL(html_file);
- return test_prerender_contents->UrlIsPending(dest_url);
+ return GetPrerenderManager()->IsPendingEntry(dest_url);
}
void set_use_https_src(bool use_https_src_server) {
@@ -804,11 +766,8 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
#endif
TestPrerenderContents* GetPrerenderContents() const {
- PrerenderManager::PrerenderData* prerender_data =
- GetPrerenderManager()->FindPrerenderData(
- dest_url_, GetSessionStorageNamespace());
return static_cast<TestPrerenderContents*>(
- prerender_data ? prerender_data->contents() : NULL);
+ GetPrerenderManager()->FindEntry(dest_url_));
}
void set_loader_path(const std::string& path) {
@@ -893,15 +852,6 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
prerender_contents_factory_);
FinalStatus expected_final_status = expected_final_status_queue.front();
- // We construct launch_nav_observer so that we can be certain our loader
- // page has finished loading before continuing. This prevents ambiguous
- // NOTIFICATION_LOAD_STOP events from making tests flaky.
- WebContents* web_contents = chrome::GetActiveWebContents(current_browser());
- ui_test_utils::WindowedNotificationObserver loader_nav_observer(
- content::NOTIFICATION_LOAD_STOP,
- content::Source<NavigationController>(
- &web_contents->GetController()));
-
// ui_test_utils::NavigateToURL uses its own observer and message loop.
// Since the test needs to wait until the prerendered page has stopped
// loading, rather than the page directly navigated to, need to
@@ -911,9 +861,6 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
false));
ui_test_utils::RunMessageLoop();
- // Now that we've run the prerender until it stopped loading, we can now
- // also make sure the launcher has finished loading.
- loader_nav_observer.Wait();
TestPrerenderContents* prerender_contents = GetPrerenderContents();
@@ -937,8 +884,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
} else {
// In the failure case, we should have removed |dest_url_| from the
// prerender_manager. We ignore dummy PrerenderContents (as indicated
- // by not having started), and PrerenderContents that are expected to
- // be left in the manager until the test finishes.
+ // by not having started).
EXPECT_TRUE(prerender_contents == NULL ||
!prerender_contents->prerendering_has_started());
}
@@ -1005,24 +951,12 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
RenderViewHost* render_view_host =
chrome::GetActiveWebContents(current_browser())->GetRenderViewHost();
-
render_view_host->ExecuteJavascriptInWebFrame(
- string16(), ASCIIToUTF16(javascript_function_name));
+ string16(),
+ ASCIIToUTF16(javascript_function_name));
- if (prerender_contents->quit_message_loop_on_destruction()) {
- // Run message loop until the prerender contents is destroyed.
- ui_test_utils::RunMessageLoop();
- } else {
- // We don't expect to pick up a running prerender, so instead
- // observe one navigation.
- content::TestNavigationObserver observer(
- content::NotificationService::AllSources(), NULL, 1);
- base::RunLoop run_loop;
- observer.WaitForObservation(
- base::Bind(&ui_test_utils::RunThisRunLoop,
- base::Unretained(&run_loop)),
- ui_test_utils::GetQuitTaskForRunLoop(&run_loop));
- }
+ // Run message loop until the prerender contents is destroyed.
+ ui_test_utils::RunMessageLoop();
}
WaitForLoadPrerenderContentsFactory* prerender_contents_factory_;
@@ -1505,14 +1439,14 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
// Next url should be in pending list but not an active entry.
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
- EXPECT_TRUE(UrlIsPending(kHtmlFileB));
+ EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
NavigateToDestURL();
// Make sure the PrerenderContents for the next url is now in the manager
// and not pending.
EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
- EXPECT_FALSE(UrlIsPending(kHtmlFileB));
+ EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
}
// Checks that we don't prerender in an infinite loop and multiple links are
@@ -1540,8 +1474,8 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
// Next url should be in pending list but not an active entry.
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
- EXPECT_TRUE(UrlIsPending(kHtmlFileB));
- EXPECT_TRUE(UrlIsPending(kHtmlFileC));
+ EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
+ EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileC));
NavigateToDestURL();
@@ -1552,8 +1486,8 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
EXPECT_TRUE((url_b_is_active_prerender || url_c_is_active_prerender) &&
!(url_b_is_active_prerender && url_c_is_active_prerender));
- EXPECT_FALSE(UrlIsPending(kHtmlFileB));
- EXPECT_FALSE(UrlIsPending(kHtmlFileC));
+ EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
+ EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileC));
}
// See crbug.com/131836.
@@ -1706,7 +1640,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRendererCrash) {
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderPageNavigateFragment) {
PrerenderTestURL("files/prerender/prerender_fragment.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_FRAGMENT_MISMATCH,
1);
NavigateToURL("files/prerender/prerender_fragment.html#fragment");
}
@@ -1717,7 +1651,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderFragmentNavigatePage) {
PrerenderTestURL("files/prerender/prerender_fragment.html#fragment",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_FRAGMENT_MISMATCH,
1);
NavigateToURL("files/prerender/prerender_fragment.html");
}
@@ -1728,7 +1662,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderFragmentNavigateFragment) {
PrerenderTestURL("files/prerender/prerender_fragment.html#other_fragment",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_FRAGMENT_MISMATCH,
1);
NavigateToURL("files/prerender/prerender_fragment.html#fragment");
}
@@ -1740,7 +1674,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderClientRedirectFromFragment) {
PrerenderTestURL(
CreateClientRedirect("files/prerender/prerender_fragment.html#fragment"),
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_FRAGMENT_MISMATCH,
2);
NavigateToURL("files/prerender/prerender_fragment.html");
}
@@ -1752,7 +1686,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderClientRedirectToFragment) {
PrerenderTestURL(
CreateClientRedirect("files/prerender/prerender_fragment.html"),
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_FRAGMENT_MISMATCH,
2);
NavigateToURL("files/prerender/prerender_fragment.html#fragment");
}
@@ -1914,7 +1848,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
PrerenderSameDomainWindowOpenerWindowOpen) {
PrerenderTestURL("files/prerender/prerender_page.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_WINDOW_OPENER,
1);
OpenDestURLViaWindowOpen();
}
@@ -1924,7 +1858,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
PrerenderSameDomainWindowOpenerClickTarget) {
PrerenderTestURL("files/prerender/prerender_page.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_WINDOW_OPENER,
1);
OpenDestURLViaClickTarget();
}
@@ -2207,21 +2141,21 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
PrerenderTestURL("files/prerender/prerender_page_with_link.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH,
1);
OpenDestURLViaClickNewWindow();
}
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
PrerenderTestURL("files/prerender/prerender_page_with_link.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH,
1);
OpenDestURLViaClickNewForegroundTab();
}
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) {
PrerenderTestURL("files/prerender/prerender_page_with_link.html",
- FINAL_STATUS_APP_TERMINATING,
+ FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH,
1);
OpenDestURLViaClickNewBackgroundTab();
}
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 0b3e1b9..6267ec2 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -5,7 +5,6 @@
#include "chrome/browser/prerender/prerender_contents.h"
#include <algorithm>
-#include <functional>
#include <utility>
#include "base/process_util.h"
@@ -13,7 +12,6 @@
#include "chrome/browser/history/history_tab_helper.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/prerender/prerender_final_status.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_render_view_host_observer.h"
#include "chrome/browser/prerender/prerender_tracker.h"
@@ -28,7 +26,6 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/session_storage_namespace.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_view.h"
@@ -38,13 +35,29 @@ using content::DownloadItem;
using content::OpenURLParams;
using content::RenderViewHost;
using content::ResourceRedirectDetails;
-using content::SessionStorageNamespace;
using content::WebContents;
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) {
+ }
+
+ 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_;
+};
+
// 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
@@ -81,6 +94,24 @@ class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
}
};
+struct PrerenderContents::PendingPrerenderInfo {
+ PendingPrerenderInfo(const GURL& url,
+ const content::Referrer& referrer,
+ const gfx::Size& size);
+ const GURL url;
+ const content::Referrer referrer;
+ const gfx::Size size;
+};
+
+PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo(
+ const GURL& url,
+ const content::Referrer& referrer,
+ const gfx::Size& size)
+ : url(url),
+ referrer(referrer),
+ size(size) {
+}
+
// TabContentsDelegateImpl -----------------------------------------------------
class PrerenderContents::TabContentsDelegateImpl
@@ -92,7 +123,7 @@ class PrerenderContents::TabContentsDelegateImpl
// content::WebContentsDelegate implementation:
virtual WebContents* OpenURLFromTab(WebContents* source,
- const OpenURLParams& params) OVERRIDE {
+ const OpenURLParams& params) OVERRIDE {
// |OpenURLFromTab| is typically called when a frame performs a navigation
// that requires the browser to perform the transition instead of WebKit.
// Examples include prerendering a site that redirects to an app URL,
@@ -188,61 +219,34 @@ class PrerenderContents::TabContentsDelegateImpl
PrerenderContents* prerender_contents_;
};
-void PrerenderContents::AddPendingPrerender(
- const base::WeakPtr<PrerenderHandle> weak_prerender_handle,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size) {
- pending_prerenders_.push_back(
- PendingPrerenderInfo(weak_prerender_handle, url, referrer, size));
+void PrerenderContents::AddPendingPrerender(const GURL& url,
+ const content::Referrer& referrer,
+ const gfx::Size& size) {
+ pending_prerender_list_.push_back(PendingPrerenderInfo(url, referrer, size));
}
-bool PrerenderContents::IsPendingEntry(
- const PrerenderHandle& prerender_handle) const {
- for (std::vector<PendingPrerenderInfo>::const_iterator it =
- pending_prerenders_.begin();
- it != pending_prerenders_.end();
+bool PrerenderContents::IsPendingEntry(const GURL& url) const {
+ for (PendingPrerenderList::const_iterator it =
+ pending_prerender_list_.begin();
+ it != pending_prerender_list_.end();
++it) {
- if (it->weak_prerender_handle.get() == &prerender_handle)
+ if (it->url == url)
return true;
}
return false;
}
void PrerenderContents::StartPendingPrerenders() {
- SessionStorageNamespace* session_storage_namespace = NULL;
- if (RenderViewHost* render_view_host = GetRenderViewHostMutable())
- session_storage_namespace = render_view_host->GetSessionStorageNamespace();
- DCHECK(child_id_ == -1 || session_storage_namespace);
-
- std::vector<PendingPrerenderInfo> pending_prerender_list;
- pending_prerender_list.swap(pending_prerenders_);
- for (std::vector<PendingPrerenderInfo>::iterator it =
- pending_prerender_list.begin();
+ 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) {
- if (it->weak_prerender_handle && it->weak_prerender_handle->IsValid()) {
- prerender_manager_->StartPendingPrerender(
- it->weak_prerender_handle.get(), ORIGIN_LINK_REL_PRERENDER, child_id_,
- it->url, it->referrer, it->size, session_storage_namespace);
- }
+ prerender_manager_->AddPrerenderFromLinkRelPrerender(
+ child_id_, route_id_, it->url, it->referrer, it->size);
}
}
-PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo(
- const base::WeakPtr<PrerenderHandle> weak_prerender_handle,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size)
- : weak_prerender_handle(weak_prerender_handle),
- url(url),
- referrer(referrer),
- size(size) {
-}
-
-PrerenderContents::PendingPrerenderInfo::~PendingPrerenderInfo() {
-}
-
PrerenderContents::PrerenderContents(
PrerenderManager* prerender_manager,
PrerenderTracker* prerender_tracker,
@@ -258,7 +262,6 @@ PrerenderContents::PrerenderContents(
referrer_(referrer),
profile_(profile),
page_id_(0),
- session_storage_namespace_id_(-1),
has_stopped_loading_(false),
has_finished_loading_(false),
final_status_(FINAL_STATUS_MAX),
@@ -272,13 +275,6 @@ PrerenderContents::PrerenderContents(
DCHECK(prerender_manager != NULL);
}
-void PrerenderContents::MakeIntoDummyReplacementOf(
- const PrerenderContents* original_prerender_contents) {
- load_start_time_ = original_prerender_contents->load_start_time_;
- session_storage_namespace_id_ =
- original_prerender_contents->session_storage_namespace_id_;
-}
-
bool PrerenderContents::Init() {
return AddAliasURL(prerender_url_);
}
@@ -291,7 +287,7 @@ PrerenderContents::Factory* PrerenderContents::CreateFactory() {
void PrerenderContents::StartPrerendering(
int creator_child_id,
const gfx::Size& size,
- SessionStorageNamespace* session_storage_namespace,
+ content::SessionStorageNamespace* session_storage_namespace,
bool is_control_group) {
DCHECK(profile_ != NULL);
DCHECK(!size.IsEmpty());
@@ -302,15 +298,11 @@ void PrerenderContents::StartPrerendering(
DCHECK_EQ(1U, alias_urls_.size());
creator_child_id_ = creator_child_id;
- session_storage_namespace_id_ = session_storage_namespace->id();
size_ = size;
InformRenderProcessAboutPrerender(prerender_url_, true,
creator_child_id_);
- DCHECK(load_start_time_.is_null());
- load_start_time_ = base::TimeTicks::Now();
-
// Everything after this point sets up the WebContents object and associated
// RenderView for the prerender page. Don't do this for members of the
// control group.
@@ -366,6 +358,9 @@ void PrerenderContents::StartPrerendering(
this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
content::Source<WebContents>(GetWebContents()));
+ DCHECK(load_start_time_.is_null());
+ load_start_time_ = base::TimeTicks::Now();
+
// Transfer over the user agent override.
new_contents->SetUserAgentOverride(
prerender_manager_->config().user_agent_override);
@@ -499,7 +494,7 @@ void PrerenderContents::OnRenderViewHostCreated(
}
WebContents* PrerenderContents::CreateWebContents(
- SessionStorageNamespace* session_storage_namespace) {
+ content::SessionStorageNamespace* session_storage_namespace) {
return WebContents::Create(profile_, NULL, MSG_ROUTING_NONE, NULL,
session_storage_namespace);
}
@@ -551,15 +546,17 @@ void PrerenderContents::AddAliasURLsFromOtherPrerenderContents(
}
}
-bool PrerenderContents::Matches(
- const GURL& url,
- const SessionStorageNamespace* session_storage_namespace) const {
- DCHECK(child_id_ == -1 || session_storage_namespace);
- if (session_storage_namespace &&
- session_storage_namespace_id_ != session_storage_namespace->id())
- return false;
- return std::count_if(alias_urls_.begin(), alias_urls_.end(),
- std::bind2nd(std::equal_to<GURL>(), url)) != 0;
+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;
+ }
+ return false;
}
void PrerenderContents::RenderViewGone(base::TerminationStatus status) {
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index 7b0a914..50bc771 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -5,12 +5,12 @@
#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_H_
+#include <list>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/prerender/prerender_final_status.h"
@@ -36,7 +36,6 @@ class WebContents;
namespace prerender {
-class PrerenderHandle;
class PrerenderManager;
class PrerenderRenderViewHostObserver;
class PrerenderTracker;
@@ -66,6 +65,10 @@ class PrerenderContents : public content::NotificationObserver,
DISALLOW_COPY_AND_ASSIGN(Factory);
};
+ // Information on pages that the prerendered page has tried to prerender.
+ struct PendingPrerenderInfo;
+ typedef std::list<PendingPrerenderInfo> PendingPrerenderList;
+
// Indicates how this PrerenderContents relates to MatchComplete. This is to
// figure out which histograms to use to record the FinalStatus, Match (record
// all prerenders and control group prerenders) or MatchComplete (record
@@ -76,7 +79,7 @@ class PrerenderContents : public content::NotificationObserver,
// MatchComplete.
MATCH_COMPLETE_DEFAULT,
// A prerender that used to be a regular prerender, but has since been
- // replaced by a MatchComplete dummy. Therefore, we will record this only
+ // replaced by a MatchComplete dummy. Therefore, we will record this only
// for Match, but not for MatchComplete.
MATCH_COMPLETE_REPLACED,
// A prerender that is a MatchComplete dummy replacing a regular prerender.
@@ -91,12 +94,6 @@ class PrerenderContents : public content::NotificationObserver,
virtual ~PrerenderContents();
- // For MatchComplete correctness, create a dummy replacement prerender
- // contents to stand in for this prerender contents that (which we are about
- // to destroy).
- void MakeIntoDummyReplacementOf(
- const PrerenderContents* original_prerender_contents);
-
bool Init();
static Factory* CreateFactory();
@@ -158,10 +155,11 @@ class PrerenderContents : public content::NotificationObserver,
base::TimeTicks load_start_time() const { return load_start_time_; }
// Indicates whether this prerendered page can be used for the provided
- // |url| and |session_storage_namespace|.
- bool Matches(
- const GURL& url,
- const content::SessionStorageNamespace* session_storage_namespace) const;
+ // URL, i.e. whether there is a match. |matching_url| is optional and will be
+ // set to the URL that is found as a match if it is provided.
+ // TODO(gavinp,mmenke): Rework matching to be based on both the URL
+ // and the session WebStorage.
+ bool MatchesURL(const GURL& url, GURL* matching_url) const;
// content::WebContentsObserver implementation.
virtual void DidStopLoading() OVERRIDE;
@@ -213,37 +211,19 @@ class PrerenderContents : public content::NotificationObserver,
// MouseEvent being dispatched by a link to a website installed as an app.
bool IsCrossSiteNavigationPending() const;
- // Adds a pending prerender to the list. If |weak_prerender_handle| still
- // exists when this page is made visible, it will be launched.
- virtual void AddPendingPrerender(
- base::WeakPtr<PrerenderHandle> weak_prerender_handle,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size);
+ // Adds a pending prerender to the list.
+ virtual void AddPendingPrerender(const GURL& url,
+ const content::Referrer& referrer,
+ const gfx::Size& size);
// Returns true if |url| corresponds to a pending prerender.
- bool IsPendingEntry(const PrerenderHandle& prerender_handle) const;
+ bool IsPendingEntry(const GURL& url) const;
// Reissues any pending prerender requests from the prerendered page. Also
// clears the list of pending requests.
void StartPendingPrerenders();
protected:
- // Information on pages that the prerendered page has tried to prerender.
- struct PendingPrerenderInfo {
- PendingPrerenderInfo(
- base::WeakPtr<PrerenderHandle> weak_prerender_handle,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size);
- ~PendingPrerenderInfo();
-
- base::WeakPtr<PrerenderHandle> weak_prerender_handle;
- GURL url;
- content::Referrer referrer;
- gfx::Size size;
- };
-
PrerenderContents(PrerenderManager* prerender_manager,
PrerenderTracker* prerender_tracker,
Profile* profile,
@@ -261,8 +241,8 @@ class PrerenderContents : public content::NotificationObserver,
return notification_registrar_;
}
- const std::vector<PendingPrerenderInfo>& pending_prerenders() const {
- return pending_prerenders_;
+ const PendingPrerenderList* pending_prerender_list() const {
+ return &pending_prerender_list_;
}
bool prerendering_has_been_cancelled() const {
@@ -274,11 +254,6 @@ class PrerenderContents : public content::NotificationObserver,
bool prerendering_has_started_;
- // Time at which we started to load the URL. This is used to compute
- // the time elapsed from initiating a prerender until the time the
- // (potentially only partially) prerendered page is shown to the user.
- base::TimeTicks load_start_time_;
-
private:
class TabContentsDelegateImpl;
@@ -327,11 +302,6 @@ class PrerenderContents : public content::NotificationObserver,
// such as HTTP redirects or javascript redirects.
std::vector<GURL> alias_urls_;
- // The session storage namespace id for use in matching. We must save it
- // rather than get it from the RenderViewHost since in the control group
- // we won't have a RenderViewHost.
- int64 session_storage_namespace_id_;
-
bool has_stopped_loading_;
// True when the main frame has finished loading.
@@ -350,6 +320,11 @@ class PrerenderContents : public content::NotificationObserver,
// Used solely to prevent double deletion.
bool prerendering_has_been_cancelled_;
+ // Time at which we started to load the URL. This is used to compute
+ // the time elapsed from initiating a prerender until the time the
+ // (potentially only partially) prerendered page is shown to the user.
+ base::TimeTicks load_start_time_;
+
// Process Metrics of the render process associated with the
// RenderViewHost for this object.
scoped_ptr<base::ProcessMetrics> process_metrics_;
@@ -372,7 +347,7 @@ class PrerenderContents : public content::NotificationObserver,
uint8 experiment_id_;
// List of all pages the prerendered page has tried to prerender.
- std::vector<PendingPrerenderInfo> pending_prerenders_;
+ PendingPrerenderList pending_prerender_list_;
// The process that created the child id.
int creator_child_id_;
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h
index 1ad3508..9bad336 100644
--- a/chrome/browser/prerender/prerender_final_status.h
+++ b/chrome/browser/prerender/prerender_final_status.h
@@ -41,14 +41,14 @@ enum FinalStatus {
FINAL_STATUS_WINDOW_OPENER = 26,
// Obsolete: FINAL_STATUS_PAGE_ID_CONFLICT = 27,
FINAL_STATUS_SAFE_BROWSING = 28,
- // Obsolete: FINAL_STATUS_FRAGMENT_MISMATCH = 29,
+ FINAL_STATUS_FRAGMENT_MISMATCH = 29,
FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED = 30,
FINAL_STATUS_CACHE_OR_HISTORY_CLEARED = 31,
FINAL_STATUS_CANCELLED = 32,
FINAL_STATUS_SSL_ERROR = 33,
FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING = 34,
FINAL_STATUS_DEVTOOLS_ATTACHED = 35,
- // Obsolete: FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH = 36,
+ FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH = 36,
// Obsolete: FINAL_STATUS_NO_USE_GROUP = 37,
// Obsolete: FINAL_STATUS_MATCH_COMPLETE_DUMMY = 38,
FINAL_STATUS_DUPLICATE = 39,
diff --git a/chrome/browser/prerender/prerender_handle.cc b/chrome/browser/prerender/prerender_handle.cc
deleted file mode 100644
index 24de791..0000000
--- a/chrome/browser/prerender/prerender_handle.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/prerender/prerender_handle.h"
-
-#include <algorithm>
-
-#include "chrome/browser/prerender/prerender_contents.h"
-
-namespace prerender {
-
-PrerenderHandle::~PrerenderHandle() {
- DCHECK(!IsValid());
- // This shouldn't occur, but we also shouldn't leak if it does.
- if (IsValid())
- OnCancel();
-}
-
-void PrerenderHandle::OnNavigateAway() {
- DCHECK(CalledOnValidThread());
- if (!IsValid())
- return;
- prerender_data_->OnNavigateAwayByHandle();
- prerender_data_.reset();
-}
-
-void PrerenderHandle::OnCancel() {
- DCHECK(CalledOnValidThread());
- if (!IsValid())
- return;
- prerender_data_->OnCancelByHandle();
- prerender_data_.reset();
-}
-
-bool PrerenderHandle::IsValid() const {
- return prerender_data_ != NULL;
-}
-
-bool PrerenderHandle::IsPending() const {
- DCHECK(CalledOnValidThread());
- return prerender_data_ && !prerender_data_->contents();
-}
-
-bool PrerenderHandle::IsPrerendering() const {
- DCHECK(CalledOnValidThread());
- return prerender_data_ && prerender_data_->contents();
-}
-
-bool PrerenderHandle::IsFinishedLoading() const {
- DCHECK(CalledOnValidThread());
- if (!prerender_data_ || IsPending())
- return false;
- return prerender_data_->contents()->has_finished_loading();
-}
-
-PrerenderHandle::PrerenderHandle(
- PrerenderManager::PrerenderData* prerender_data)
- : prerender_data_(prerender_data->AsWeakPtr()),
- weak_ptr_factory_(this) {
- prerender_data->OnNewHandle();
-}
-
-void PrerenderHandle::SwapPrerenderDataWith(
- PrerenderHandle* other_prerender_handle) {
- DCHECK(CalledOnValidThread());
- DCHECK(other_prerender_handle);
- std::swap(prerender_data_, other_prerender_handle->prerender_data_);
-}
-
-} // namespace prerender
diff --git a/chrome/browser/prerender/prerender_handle.h b/chrome/browser/prerender/prerender_handle.h
deleted file mode 100644
index 90a9dcc..0000000
--- a/chrome/browser/prerender/prerender_handle.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_HANDLE_H_
-#define CHROME_BROWSER_PRERENDER_PRERENDER_HANDLE_H_
-
-#include "base/basictypes.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "chrome/browser/prerender/prerender_manager.h"
-
-class GURL;
-
-namespace content {
-class SessionStorageNamespace;
-}
-
-namespace prerender {
-
-class PrerenderContents;
-
-// A class representing a running prerender to a client of the PrerenderManager.
-// Methods on PrerenderManager which start prerenders return a caller-owned
-// PrerenderHandle* to the client (or NULL if they are unable to start a
-// prerender). Because the PrerenderManager can stop running prerenders at any
-// time, callers may wish to check PrerenderHandle::IsValid() before operating
-// on their prerenders.
-class PrerenderHandle : public base::NonThreadSafe {
- public:
- // Before calling the destructor, the caller must invalidate the handle by
- // calling either OnNavigateAway or OnCancel.
- ~PrerenderHandle();
-
- // The launcher is navigating away from the context that launched this
- // prerender. The prerender will likely stay alive briefly though, in case we
- // are going through a redirect chain that will target it. This call
- // invalidates the handle. If the prerender handle is already invalid, this
- // call does nothing.
- void OnNavigateAway();
-
- // The launcher has taken explicit action to remove this prerender (for
- // instance, removing a link element from a document). This call invalidates
- // the handle. If the prerender handle is already invalid, this call does
- // nothing.
- void OnCancel();
-
- // True if the prerender handle is still connected to a (pending or running)
- // prerender. Handles can become invalid through explicit requests by the
- // client, such as calling OnCancel() or OnNavigateAway(), and handles
- // also become invalid when the PrerenderManager cancels prerenders.
- bool IsValid() const;
-
- // True if this prerender was launched by a page that was itself being
- // prerendered, and so has not yet been started.
- bool IsPending() const;
-
- // True if this prerender is currently active.
- bool IsPrerendering() const;
-
- // True if we started a prerender, and it has finished loading.
- bool IsFinishedLoading() const;
-
- private:
- friend class PrerenderManager;
-
- explicit PrerenderHandle(PrerenderManager::PrerenderData* prerender_data);
-
- void SwapPrerenderDataWith(PrerenderHandle* other_prerender_handle);
-
- base::WeakPtr<PrerenderManager::PrerenderData> prerender_data_;
- base::WeakPtrFactory<PrerenderHandle> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PrerenderHandle);
-};
-
-} // namespace prerender
-
-#endif // CHROME_BROWSER_PRERENDER_PRERENDER_HANDLE_H_
diff --git a/chrome/browser/prerender/prerender_link_manager.cc b/chrome/browser/prerender/prerender_link_manager.cc
index 27793ee..c12e6cc 100644
--- a/chrome/browser/prerender/prerender_link_manager.cc
+++ b/chrome/browser/prerender/prerender_link_manager.cc
@@ -9,7 +9,6 @@
#include <utility>
#include "chrome/browser/prerender/prerender_contents.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
@@ -30,13 +29,6 @@ PrerenderLinkManager::PrerenderLinkManager(PrerenderManager* manager)
}
PrerenderLinkManager::~PrerenderLinkManager() {
- for (IdPairToPrerenderHandleMap::iterator it = ids_to_handle_map_.begin();
- it != ids_to_handle_map_.end();
- ++it) {
- PrerenderHandle* prerender_handle = it->second;
- prerender_handle->OnCancel();
- delete prerender_handle;
- }
}
bool PrerenderLinkManager::OnAddPrerender(int child_id,
@@ -52,28 +44,20 @@ bool PrerenderLinkManager::OnAddPrerender(int child_id,
<< ", size = (" << size.width() << ", " << size.height() << ")"
<< ", render_view_route_id = " << render_view_route_id;
- const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id);
- DCHECK_EQ(0U, ids_to_handle_map_.count(child_and_prerender_id));
-
// TODO(gavinp): Add tests to ensure fragments work, then remove this fragment
// clearing code.
url_canon::Replacements<char> replacements;
replacements.ClearRef();
const GURL url = orig_url.ReplaceComponents(replacements);
- scoped_ptr<PrerenderHandle> prerender_handle(
- manager_->AddPrerenderFromLinkRelPrerender(
- child_id, render_view_route_id, url, referrer, size));
- if (prerender_handle.get()) {
- std::pair<IdPairToPrerenderHandleMap::iterator, bool> insert_result =
- ids_to_handle_map_.insert(IdPairToPrerenderHandleMap::value_type(
- child_and_prerender_id, NULL));
- DCHECK(insert_result.second);
- delete insert_result.first->second;
- insert_result.first->second = prerender_handle.release();
- return true;
+ if (!manager_->AddPrerenderFromLinkRelPrerender(
+ child_id, render_view_route_id, url, referrer, size)) {
+ return false;
}
- return false;
+ const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id);
+ DCHECK_EQ(0U, ids_to_url_map_.count(child_and_prerender_id));
+ ids_to_url_map_.insert(std::make_pair(child_and_prerender_id, url));
+ return true;
}
// TODO(gavinp): Once an observer interface is provided down to the WebKit
@@ -85,28 +69,24 @@ void PrerenderLinkManager::OnCancelPrerender(int child_id, int prerender_id) {
DVLOG(2) << "OnCancelPrerender, child_id = " << child_id
<< ", prerender_id = " << prerender_id;
const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id);
- IdPairToPrerenderHandleMap::iterator id_to_handle_iter =
- ids_to_handle_map_.find(child_and_prerender_id);
- if (id_to_handle_iter == ids_to_handle_map_.end()) {
+ IdPairToUrlMap::iterator id_url_iter =
+ ids_to_url_map_.find(child_and_prerender_id);
+ if (id_url_iter == ids_to_url_map_.end()) {
DVLOG(5) << "... canceling a prerender that doesn't exist.";
return;
}
- PrerenderHandle* prerender_handle = id_to_handle_iter->second;
- prerender_handle->OnCancel();
- RemovePrerender(id_to_handle_iter);
+ const GURL url = id_url_iter->second;
+ ids_to_url_map_.erase(id_url_iter);
+ manager_->MaybeCancelPrerender(url);
}
void PrerenderLinkManager::OnAbandonPrerender(int child_id, int prerender_id) {
DVLOG(2) << "OnAbandonPrerender, child_id = " << child_id
<< ", prerender_id = " << prerender_id;
+ // TODO(gavinp,cbentzel): Implement reasonable behaviour for
+ // navigation away from launcher.
const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id);
- IdPairToPrerenderHandleMap::iterator id_to_handle_iter =
- ids_to_handle_map_.find(child_and_prerender_id);
- if (id_to_handle_iter == ids_to_handle_map_.end())
- return;
- PrerenderHandle* prerender_handle = id_to_handle_iter->second;
- prerender_handle->OnNavigateAway();
- RemovePrerender(id_to_handle_iter);
+ ids_to_url_map_.erase(child_and_prerender_id);
}
void PrerenderLinkManager::OnChannelClosing(int child_id) {
@@ -116,9 +96,9 @@ void PrerenderLinkManager::OnChannelClosing(int child_id) {
const ChildAndPrerenderIdPair child_and_maximum_prerender_id(
child_id, std::numeric_limits<int>::max());
std::queue<int> prerender_ids_to_abandon;
- for (IdPairToPrerenderHandleMap::iterator
- i = ids_to_handle_map_.lower_bound(child_and_minimum_prerender_id),
- e = ids_to_handle_map_.upper_bound(child_and_maximum_prerender_id);
+ for (IdPairToUrlMap::iterator
+ i = ids_to_url_map_.lower_bound(child_and_minimum_prerender_id),
+ e = ids_to_url_map_.upper_bound(child_and_maximum_prerender_id);
i != e; ++i) {
prerender_ids_to_abandon.push(i->first.second);
}
@@ -131,14 +111,8 @@ void PrerenderLinkManager::OnChannelClosing(int child_id) {
}
bool PrerenderLinkManager::IsEmpty() const {
- return ids_to_handle_map_.empty();
-}
-
-void PrerenderLinkManager::RemovePrerender(
- const IdPairToPrerenderHandleMap::iterator& id_to_handle_iter) {
- PrerenderHandle* prerender_handle = id_to_handle_iter->second;
- delete prerender_handle;
- ids_to_handle_map_.erase(id_to_handle_iter);
+ return ids_to_url_map_.empty();
}
} // namespace prerender
+
diff --git a/chrome/browser/prerender/prerender_link_manager.h b/chrome/browser/prerender/prerender_link_manager.h
index d9e9c00..5f091c2 100644
--- a/chrome/browser/prerender/prerender_link_manager.h
+++ b/chrome/browser/prerender/prerender_link_manager.h
@@ -9,6 +9,7 @@
#include <utility>
#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "googleurl/src/gurl.h"
@@ -24,7 +25,6 @@ class Size;
namespace prerender {
-class PrerenderHandle;
class PrerenderManager;
// PrerenderLinkManager implements the API on Link elements for all documents
@@ -69,20 +69,14 @@ class PrerenderLinkManager : public ProfileKeyedService {
friend class PrerenderTest;
typedef std::pair<int, int> ChildAndPrerenderIdPair;
- typedef std::map<ChildAndPrerenderIdPair, PrerenderHandle*>
- IdPairToPrerenderHandleMap;
+ typedef std::map<ChildAndPrerenderIdPair, GURL> IdPairToUrlMap;
- void RemovePrerender(
- const IdPairToPrerenderHandleMap::iterator& id_to_handle_iter);
+ void RemovePrerender(const IdPairToUrlMap::iterator& id_url_iter);
bool IsEmpty() const;
PrerenderManager* manager_;
-
- // A map from child process id and prerender id to PrerenderHandles. We map
- // from this pair because the prerender ids are only unique within their
- // renderer process.
- IdPairToPrerenderHandleMap ids_to_handle_map_;
+ IdPairToUrlMap ids_to_url_map_;
DISALLOW_COPY_AND_ASSIGN(PrerenderLinkManager);
};
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 6eee18a..5d04091 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -4,8 +4,7 @@
#include "chrome/browser/prerender/prerender_manager.h"
-#include <algorithm>
-#include <functional>
+#include <set>
#include <string>
#include <vector>
@@ -25,7 +24,6 @@
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_field_trial.h"
#include "chrome/browser/prerender/prerender_final_status.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_histograms.h"
#include "chrome/browser/prerender/prerender_history.h"
#include "chrome/browser/prerender/prerender_local_predictor.h"
@@ -108,8 +106,10 @@ bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) {
final_status != FINAL_STATUS_MANAGER_SHUTDOWN &&
final_status != FINAL_STATUS_APP_TERMINATING &&
final_status != FINAL_STATUS_WINDOW_OPENER &&
+ final_status != FINAL_STATUS_FRAGMENT_MISMATCH &&
final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED &&
final_status != FINAL_STATUS_CANCELLED &&
+ final_status != FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH &&
final_status != FINAL_STATUS_DEVTOOLS_ATTACHED &&
final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING;
}
@@ -171,6 +171,18 @@ int PrerenderManager::prerenders_per_session_count_ = 0;
PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ =
PRERENDER_MODE_ENABLED;
+struct PrerenderManager::PrerenderContentsData {
+ PrerenderContents* contents_;
+ base::Time start_time_;
+ int active_count_;
+ PrerenderContentsData(PrerenderContents* contents, base::Time start_time)
+ : contents_(contents),
+ start_time_(start_time),
+ active_count_(1) {
+ CHECK(contents);
+ }
+};
+
struct PrerenderManager::NavigationRecord {
GURL url_;
base::TimeTicks time_;
@@ -205,32 +217,25 @@ void PrerenderManager::Shutdown() {
DoShutdown();
}
-PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender(
+bool PrerenderManager::AddPrerenderFromLinkRelPrerender(
int process_id,
int route_id,
const GURL& url,
const content::Referrer& referrer,
- const gfx::Size& size) {
+ gfx::Size size) {
#if defined(OS_ANDROID)
// TODO(jcivelli): http://crbug.com/113322 We should have an option to disable
// link-prerender and enable omnibox-prerender only.
return false;
#else
- DCHECK(!size.IsEmpty());
- if (PrerenderData* parent_prerender_data =
- FindPrerenderDataForChildAndRoute(process_id, route_id)) {
+ std::pair<int, int> child_route_id_pair(process_id, route_id);
+ PrerenderContentsDataList::iterator it =
+ FindPrerenderContentsForChildRouteIdPair(child_route_id_pair);
+ if (it != prerender_list_.end()) {
// Instead of prerendering from inside of a running prerender, we will defer
// this request until its launcher is made visible.
- if (PrerenderContents* contents = parent_prerender_data->contents_) {
- pending_prerender_list_.push_back(
- linked_ptr<PrerenderData>(new PrerenderData(this)));
- PrerenderHandle* prerender_handle =
- new PrerenderHandle(pending_prerender_list_.back().get());
- contents->AddPendingPrerender(
- prerender_handle->weak_ptr_factory_.GetWeakPtr(),
- url, referrer, size);
- return prerender_handle;
- }
+ it->contents_->AddPendingPrerender(url, referrer, size);
+ return true;
}
// Unit tests pass in a process_id == -1.
@@ -238,10 +243,21 @@ PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender(
if (process_id != -1) {
RenderViewHost* source_render_view_host =
RenderViewHost::FromID(process_id, route_id);
- if (!source_render_view_host)
- return NULL;
+ if (!source_render_view_host || !source_render_view_host->GetView())
+ return false;
session_storage_namespace =
source_render_view_host->GetSessionStorageNamespace();
+
+ if (size.IsEmpty()) {
+ // Use the size of the tab requesting the prerendering.
+ WebContents* web_contents =
+ WebContents::FromRenderViewHost(source_render_view_host);
+ if (web_contents && web_contents->GetView()) {
+ gfx::Rect container_bounds;
+ web_contents->GetView()->GetContainerBounds(&container_bounds);
+ size = container_bounds.size();
+ }
+ }
}
return AddPrerender(ORIGIN_LINK_REL_PRERENDER,
@@ -250,31 +266,44 @@ PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender(
#endif
}
-PrerenderHandle* PrerenderManager::AddPrerenderFromOmnibox(
+bool PrerenderManager::AddPrerenderFromOmnibox(
const GURL& url,
SessionStorageNamespace* session_storage_namespace,
- const gfx::Size& size) {
+ gfx::Size size) {
if (!IsOmniboxEnabled(profile_))
- return NULL;
- return AddPrerender(ORIGIN_OMNIBOX, -1, url, content::Referrer(), size,
+ return false;
+ return AddPrerender(ORIGIN_OMNIBOX, -1, url,
+ content::Referrer(), size,
session_storage_namespace);
}
+void PrerenderManager::MaybeCancelPrerender(const GURL& url) {
+ PrerenderContentsDataList::iterator it = FindPrerenderContentsForURL(url);
+ if (it == prerender_list_.end())
+ return;
+ PrerenderContentsData& prerender_contents_data = *it;
+ if (--prerender_contents_data.active_count_ == 0)
+ prerender_contents_data.contents_->Destroy(FINAL_STATUS_CANCELLED);
+}
+
void PrerenderManager::DestroyPrerenderForRenderView(
int process_id, int view_id, FinalStatus final_status) {
DCHECK(CalledOnValidThread());
- if (PrerenderData* prerender_data =
- FindPrerenderDataForChildAndRoute(process_id, view_id)) {
- prerender_data->contents_->Destroy(final_status);
+ PrerenderContentsDataList::iterator it =
+ FindPrerenderContentsForChildRouteIdPair(
+ std::make_pair(process_id, view_id));
+ if (it != prerender_list_.end()) {
+ PrerenderContents* prerender_contents = it->contents_;
+ prerender_contents->Destroy(final_status);
}
}
void PrerenderManager::CancelAllPrerenders() {
DCHECK(CalledOnValidThread());
- while (!active_prerender_list_.empty()) {
- PrerenderContents* prerender_contents =
- active_prerender_list_.front()->contents();
- prerender_contents->Destroy(FINAL_STATUS_CANCELLED);
+ while (!prerender_list_.empty()) {
+ PrerenderContentsData data = prerender_list_.front();
+ DCHECK(data.contents_);
+ data.contents_->Destroy(FINAL_STATUS_CANCELLED);
}
}
@@ -283,37 +312,27 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
DCHECK(CalledOnValidThread());
DCHECK(!IsWebContentsPrerendering(web_contents));
- RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost();
-
- DeleteOldEntries();
- DeletePendingDeleteEntries();
- PrerenderData* prerender_data = FindPrerenderData(
- url, old_render_view_host->GetSessionStorageNamespace());
- if (!prerender_data)
- return false;
- DCHECK(prerender_data->contents_);
- if (IsNoSwapInExperiment(prerender_data->contents_->experiment_id()))
+ scoped_ptr<PrerenderContents> prerender_contents(
+ GetEntryButNotSpecifiedWC(url, web_contents));
+ if (prerender_contents.get() == NULL)
return false;
- if (TabContents* new_tab_contents =
- prerender_data->contents_->prerender_contents()) {
- if (web_contents == new_tab_contents->web_contents())
- return false; // Do not swap in to ourself.
- }
-
- scoped_ptr<PrerenderContents> prerender_contents(prerender_data->contents_);
- std::list<linked_ptr<PrerenderData> >::iterator to_erase =
- FindIteratorForPrerenderContents(prerender_contents.get());
- DCHECK(active_prerender_list_.end() != to_erase);
- DCHECK_EQ(prerender_data, to_erase->get());
- active_prerender_list_.erase(to_erase);
-
// Do not use the prerendered version if there is an opener object.
if (web_contents->HasOpener()) {
prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER);
return false;
}
+ // Even if we match, the location.hash might be different. Record this as a
+ // separate final status.
+ GURL matching_url;
+ bool url_matches = prerender_contents->MatchesURL(url, &matching_url);
+ DCHECK(url_matches);
+ if (url_matches && url.ref() != matching_url.ref()) {
+ prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH);
+ return false;
+ }
+
// If we are just in the control group (which can be detected by noticing
// that prerendering hasn't even started yet), record that |web_contents| now
// would be showing a prerendered contents, but otherwise, don't do anything.
@@ -340,6 +359,22 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
return false;
}
+ // If the session storage namespaces don't match, cancel the prerender.
+ RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost();
+ RenderViewHost* new_render_view_host =
+ prerender_contents->prerender_contents()->web_contents()->
+ GetRenderViewHost();
+ DCHECK(old_render_view_host);
+ DCHECK(new_render_view_host);
+ if (old_render_view_host->GetSessionStorageNamespace() !=
+ new_render_view_host->GetSessionStorageNamespace()) {
+ DestroyAndMarkMatchCompleteAsUsed(
+ prerender_contents.release(),
+ FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH);
+ return false;
+ }
+
+ // If we don't want to use prerenders at all, we are done.
// For bookkeeping purposes, we need to mark this WebContents to
// reflect that it would have been prerendered.
if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
@@ -358,8 +393,6 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
if (!prerender_tracker_->TryUse(child_id, route_id))
return false;
- // At this point, we've determined that we will use the prerender.
-
if (!prerender_contents->load_start_time().is_null()) {
histograms_->RecordTimeUntilUsed(GetCurrentTimeTicks() -
prerender_contents->load_start_time(),
@@ -370,17 +403,10 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
histograms_->RecordUsedPrerender(prerender_contents->origin());
prerender_contents->set_final_status(FINAL_STATUS_USED);
- RenderViewHost* new_render_view_host =
- prerender_contents->prerender_contents()->web_contents()->
- GetRenderViewHost();
new_render_view_host->Send(
new PrerenderMsg_SetIsPrerendering(new_render_view_host->GetRoutingID(),
false));
- // Start pending prerender requests from the PrerenderContents, if there are
- // any.
- prerender_contents->StartPendingPrerenders();
-
TabContents* new_tab_contents =
prerender_contents->ReleasePrerenderContents();
TabContents* old_tab_contents = TabContents::FromWebContents(web_contents);
@@ -413,6 +439,10 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
DCHECK(prerender_tab_helper != NULL);
prerender_tab_helper->PrerenderSwappedIn();
+ // Start pending prerender requests from the PrerenderContents, if there are
+ // any.
+ prerender_contents->StartPendingPrerenders();
+
if (old_tab_contents->web_contents()->NeedToFireBeforeUnload()) {
// Schedule the delete to occur after the tab has run its unload handlers.
on_close_tab_contents_deleters_.push_back(
@@ -439,46 +469,50 @@ void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry,
DCHECK_EQ(0, std::count(pending_delete_list_.begin(),
pending_delete_list_.end(), entry));
- std::list<linked_ptr<PrerenderData> >::iterator it =
- FindIteratorForPrerenderContents(entry);
-
- // If this PrerenderContents is being deleted due to a cancellation,
- // we need to create a dummy replacement for PPLT accounting purposes
- // for the Match Complete group.
- // This is the case if the cancellation is for any reason that would not
- // occur in the control group case.
- if (it != active_prerender_list_.end()) {
- if (entry->match_complete_status() ==
- PrerenderContents::MATCH_COMPLETE_DEFAULT &&
- NeedMatchCompleteDummyForFinalStatus(final_status) &&
- ActuallyPrerendering()) {
- // TODO(tburkard): I'd like to DCHECK that we are actually prerendering.
- // However, what if new conditions are added and
- // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure
- // what's the best thing to do here. For now, I will just check whether
- // we are actually prerendering.
- entry->set_match_complete_status(
- PrerenderContents::MATCH_COMPLETE_REPLACED);
- PrerenderContents* dummy_replacement_prerender_contents =
- CreatePrerenderContents(entry->prerender_url(), entry->referrer(),
- entry->origin(), entry->experiment_id());
- dummy_replacement_prerender_contents->MakeIntoDummyReplacementOf(entry);
- DCHECK(dummy_replacement_prerender_contents);
-
- dummy_replacement_prerender_contents->set_match_complete_status(
- PrerenderContents::MATCH_COMPLETE_REPLACEMENT_PENDING);
- DCHECK(dummy_replacement_prerender_contents->Init());
- dummy_replacement_prerender_contents->
- AddAliasURLsFromOtherPrerenderContents(entry);
- dummy_replacement_prerender_contents->set_match_complete_status(
- PrerenderContents::MATCH_COMPLETE_REPLACEMENT);
-
- it->get()->contents_ = dummy_replacement_prerender_contents;
- } else {
- active_prerender_list_.erase(it);
+ for (PrerenderContentsDataList::iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
+ ++it) {
+ if (it->contents_ == entry) {
+ bool swapped_in_dummy_replacement = false;
+
+ // If this PrerenderContents is being deleted due to a cancellation,
+ // we need to create a dummy replacement for PPLT accounting purposes
+ // for the Match Complete group.
+ // This is the case if the cancellation is for any reason that would not
+ // occur in the control group case.
+ if (entry->match_complete_status() ==
+ PrerenderContents::MATCH_COMPLETE_DEFAULT &&
+ NeedMatchCompleteDummyForFinalStatus(final_status) &&
+ ActuallyPrerendering()) {
+ // TODO(tburkard): I'd like to DCHECK that we are actually prerendering.
+ // However, what if new conditions are added and
+ // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure
+ // what's the best thing to do here. For now, I will just check whether
+ // we are actually prerendering.
+ entry->set_match_complete_status(
+ PrerenderContents::MATCH_COMPLETE_REPLACED);
+ if (PrerenderContents* dummy_replacement_prerender_contents =
+ CreatePrerenderContents(entry->prerender_url(),
+ entry->referrer(),
+ entry->origin(),
+ entry->experiment_id())) {
+ dummy_replacement_prerender_contents->set_match_complete_status(
+ PrerenderContents::MATCH_COMPLETE_REPLACEMENT_PENDING);
+ if (!dummy_replacement_prerender_contents->Init())
+ break;
+ dummy_replacement_prerender_contents->
+ AddAliasURLsFromOtherPrerenderContents(entry);
+ dummy_replacement_prerender_contents->set_match_complete_status(
+ PrerenderContents::MATCH_COMPLETE_REPLACEMENT);
+ it->contents_ = dummy_replacement_prerender_contents;
+ swapped_in_dummy_replacement = true;
+ }
+ }
+ if (!swapped_in_dummy_replacement)
+ prerender_list_.erase(it);
+ break;
}
}
-
AddToHistory(entry);
pending_delete_list_.push_back(entry);
@@ -589,12 +623,10 @@ bool PrerenderManager::IsNoUseGroup() {
bool PrerenderManager::IsWebContentsPrerendering(
WebContents* web_contents) const {
DCHECK(CalledOnValidThread());
- for (std::list<linked_ptr<PrerenderData> >::const_iterator it =
- active_prerender_list_.begin();
- it != active_prerender_list_.end();
+ for (PrerenderContentsDataList::const_iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
++it) {
- TabContents* prerender_tab_contents =
- it->get()->contents_->prerender_contents();
+ TabContents* prerender_tab_contents = it->contents_->prerender_contents();
if (prerender_tab_contents &&
prerender_tab_contents->web_contents() == web_contents) {
return true;
@@ -615,6 +647,12 @@ bool PrerenderManager::IsWebContentsPrerendering(
return false;
}
+bool PrerenderManager::DidPrerenderFinishLoading(const GURL& url) const {
+ DCHECK(CalledOnValidThread());
+ PrerenderContents* contents = FindEntry(url);
+ return contents ? contents->has_finished_loading() : false;
+}
+
void PrerenderManager::MarkWebContentsAsPrerendered(WebContents* web_contents) {
DCHECK(CalledOnValidThread());
prerendered_tab_contents_set_.insert(web_contents);
@@ -730,142 +768,55 @@ void PrerenderManager::AddCondition(const PrerenderCondition* condition) {
prerender_conditions_.push_back(condition);
}
-void PrerenderManager::RecordNavigation(const GURL& url) {
+bool PrerenderManager::IsPendingEntry(const GURL& url) const {
DCHECK(CalledOnValidThread());
-
- navigations_.push_back(NavigationRecord(url, GetCurrentTimeTicks()));
- CleanUpOldNavigations();
-}
-
-// protected
-PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager)
- : manager_(manager), contents_(NULL), handle_count_(0) {
-}
-
-PrerenderManager::PrerenderData::PrerenderData(PrerenderManager* manager,
- PrerenderContents* contents)
- : manager_(manager), contents_(contents), handle_count_(0) {
-}
-
-void PrerenderManager::PrerenderData::OnNewHandle() {
- DCHECK(contents_ || handle_count_ == 0) <<
- "Cannot create multiple handles to a pending prerender.";
- ++handle_count_;
-}
-
-void PrerenderManager::PrerenderData::OnNavigateAwayByHandle() {
- // TODO(gavinp): Implement reasonable behaviour for navigation away from
- // launcher. We can't just call OnCancel, because many cases have redirect
- // chains that will eventually lead to the correct prerendered page, and we
- // don't want to delete our prerender just as it is going to be used.
-
- if (!contents_) {
- DCHECK_EQ(1, handle_count_);
- // Pending prerenders are not maintained in the active_prerender_list_, so
- // they will not get normal expiry. Since this prerender hasn't even been
- // launched yet, and it's held by a page that is being prerendered, we will
- // just delete it.
- manager_->DestroyPendingPrerenderData(this);
+ for (PrerenderContentsDataList::const_iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
+ ++it) {
+ if (it->contents_->IsPendingEntry(url))
+ return true;
}
+ return false;
}
-void PrerenderManager::PrerenderData::OnCancelByHandle() {
- DCHECK_LE(1, handle_count_);
- DCHECK(contents_ || handle_count_ == 1);
-
- if (--handle_count_ == 0) {
- if (contents_) {
- // This will eventually remove this object from active_prerender_list_,
- // triggering the linked_ptr auto deletion.
- contents_->Destroy(FINAL_STATUS_CANCELLED);
- } else {
- manager_->DestroyPendingPrerenderData(this);
- }
- }
+bool PrerenderManager::IsPrerendering(const GURL& url) const {
+ DCHECK(CalledOnValidThread());
+ return (FindEntry(url) != NULL);
}
-PrerenderManager::PrerenderData::~PrerenderData() {
+void PrerenderManager::RecordNavigation(const GURL& url) {
+ DCHECK(CalledOnValidThread());
+
+ navigations_.push_back(NavigationRecord(url, GetCurrentTimeTicks()));
+ CleanUpOldNavigations();
}
+// protected
void PrerenderManager::SetPrerenderContentsFactory(
PrerenderContents::Factory* prerender_contents_factory) {
DCHECK(CalledOnValidThread());
prerender_contents_factory_.reset(prerender_contents_factory);
}
-void PrerenderManager::StartPendingPrerender(
- PrerenderHandle* existing_prerender_handle,
- Origin origin,
- int process_id,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size,
- content::SessionStorageNamespace* session_storage_namespace) {
- DCHECK(existing_prerender_handle);
- DCHECK(existing_prerender_handle->IsValid());
- DCHECK(existing_prerender_handle->IsPending());
-
- DVLOG(6) << "StartPendingPrerender";
- DVLOG(6) << "existing_prerender_handle->handle_count_ = " <<
- existing_prerender_handle->prerender_data_->handle_count_;
-
- DCHECK(process_id == -1 || session_storage_namespace);
-
- scoped_ptr<PrerenderHandle> swap_prerender_handle(AddPrerender(
- origin, process_id, url, referrer, size, session_storage_namespace));
- if (swap_prerender_handle.get()) {
- // AddPrerender has returned a new prerender handle to us. We want to make
- // |existing_prerender_handle| active, so swap the underlying PrerenderData
- // between the two handles, and delete our old handle (which will release
- // our entry in the pending_prerender_list_).
- existing_prerender_handle->SwapPrerenderDataWith(
- swap_prerender_handle.get());
- swap_prerender_handle->OnCancel();
- return;
- }
-
- // We could not start our Prerender. Canceling the existing handle will make
- // it return false for PrerenderHandle::IsPending(), and will release the
- // PrerenderData from pending_prerender_list_.
- existing_prerender_handle->OnCancel();
-}
-
-void PrerenderManager::DestroyPendingPrerenderData(
- PrerenderData* pending_prerender_data) {
- for (std::list<linked_ptr<PrerenderData> >::iterator
- it = pending_prerender_list_.begin();
- it != pending_prerender_list_.end();
- ++it) {
- if (it->get() == pending_prerender_data) {
- DCHECK_GE(1, it->get()->handle_count_);
- pending_prerender_list_.erase(it);
- return;
- }
- }
- NOTREACHED();
-}
-
void PrerenderManager::DoShutdown() {
DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN);
STLDeleteElements(&prerender_conditions_);
on_close_tab_contents_deleters_.reset();
profile_ = NULL;
-
- DCHECK(active_prerender_list_.empty());
}
// private
-PrerenderHandle* PrerenderManager::AddPrerender(
+bool PrerenderManager::AddPrerender(
Origin origin,
int process_id,
const GURL& url_arg,
const content::Referrer& referrer,
- const gfx::Size& size,
+ gfx::Size size,
SessionStorageNamespace* session_storage_namespace) {
DCHECK(CalledOnValidThread());
if (!IsEnabled())
- return NULL;
+ return false;
if (origin == ORIGIN_LINK_REL_PRERENDER &&
IsGoogleSearchResultURL(referrer.url)) {
@@ -889,10 +840,10 @@ PrerenderHandle* PrerenderManager::AddPrerender(
// histogram tracking.
histograms_->RecordPrerender(origin, url_arg);
- if (PrerenderData* preexisting_prerender_data =
- FindPrerenderData(url, session_storage_namespace)) {
+ if (PrerenderContentsData* prerender_contents_data = FindEntryData(url)) {
+ ++prerender_contents_data->active_count_;
RecordFinalStatus(origin, experiment, FINAL_STATUS_DUPLICATE);
- return new PrerenderHandle(preexisting_prerender_data);
+ return true;
}
// Do not prerender if there are too many render processes, and we would
@@ -910,7 +861,7 @@ PrerenderHandle* PrerenderManager::AddPrerender(
profile_, url) &&
!content::RenderProcessHost::run_renderer_in_process()) {
RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
- return NULL;
+ return false;
}
#endif
@@ -920,39 +871,64 @@ PrerenderHandle* PrerenderManager::AddPrerender(
// this doesn't make sense as the next prerender request will be triggered
// by a navigation and is unlikely to be the same site.
RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
- return NULL;
+ return false;
}
PrerenderContents* prerender_contents = CreatePrerenderContents(
url, referrer, origin, experiment);
if (!prerender_contents || !prerender_contents->Init())
- return NULL;
+ return false;
histograms_->RecordPrerenderStarted(origin);
// TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
- active_prerender_list_.push_back(
- linked_ptr<PrerenderData>(new PrerenderData(this, prerender_contents)));
- PrerenderHandle* prerender_handle =
- new PrerenderHandle(active_prerender_list_.back().get());
+ PrerenderContentsData data(prerender_contents, GetCurrentTime());
+
+ prerender_list_.push_back(data);
last_prerender_start_time_ = GetCurrentTimeTicks();
- gfx::Size contents_size =
- size.IsEmpty() ? config_.default_tab_bounds.size() : size;
+ if (size.IsEmpty())
+ size = config_.default_tab_bounds.size();
- prerender_contents->StartPrerendering(process_id, contents_size,
- session_storage_namespace,
- control_group_behavior);
+ data.contents_->StartPrerendering(process_id, size, session_storage_namespace,
+ control_group_behavior);
- while (active_prerender_list_.size() > config_.max_elements) {
- prerender_contents = active_prerender_list_.front()->contents_;
- DCHECK(prerender_contents);
- prerender_contents->Destroy(FINAL_STATUS_EVICTED);
+ while (prerender_list_.size() > config_.max_elements) {
+ data = prerender_list_.front();
+ prerender_list_.pop_front();
+ data.contents_->Destroy(FINAL_STATUS_EVICTED);
}
-
StartSchedulingPeriodicCleanups();
- return prerender_handle;
+ return true;
+}
+
+PrerenderContents* PrerenderManager::GetEntry(const GURL& url) {
+ return GetEntryButNotSpecifiedWC(url, NULL);
+}
+
+PrerenderContents* PrerenderManager::GetEntryButNotSpecifiedWC(
+ const GURL& url,
+ WebContents* wc) {
+ DCHECK(CalledOnValidThread());
+ DeleteOldEntries();
+ DeletePendingDeleteEntries();
+ for (PrerenderContentsDataList::iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
+ ++it) {
+ PrerenderContents* prerender_contents = it->contents_;
+ if (prerender_contents->MatchesURL(url, NULL) &&
+ !IsNoSwapInExperiment(prerender_contents->experiment_id())) {
+ if (!prerender_contents->prerender_contents() ||
+ !wc ||
+ prerender_contents->prerender_contents()->web_contents() != wc) {
+ prerender_list_.erase(it);
+ return prerender_contents;
+ }
+ }
+ }
+ // Entry not found.
+ return NULL;
}
void PrerenderManager::StartSchedulingPeriodicCleanups() {
@@ -965,7 +941,10 @@ void PrerenderManager::StartSchedulingPeriodicCleanups() {
&PrerenderManager::PeriodicCleanup);
}
-void PrerenderManager::StopSchedulingPeriodicCleanups() {
+void PrerenderManager::MaybeStopSchedulingPeriodicCleanups() {
+ if (!prerender_list_.empty())
+ return;
+
DCHECK(CalledOnValidThread());
repeating_timer_.Stop();
}
@@ -974,22 +953,22 @@ void PrerenderManager::PeriodicCleanup() {
DCHECK(CalledOnValidThread());
DeleteOldTabContents();
DeleteOldEntries();
- if (active_prerender_list_.empty())
- StopSchedulingPeriodicCleanups();
// Grab a copy of the current PrerenderContents pointers, so that we
// will not interfere with potential deletions of the list.
std::vector<PrerenderContents*> prerender_contents;
- prerender_contents.reserve(active_prerender_list_.size());
- for (std::list<linked_ptr<PrerenderData> >::iterator
- it = active_prerender_list_.begin();
- it != active_prerender_list_.end();
- ++it) {
- prerender_contents.push_back(it->get()->contents_);
+ for (PrerenderContentsDataList::iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
+ ++it) {
+ DCHECK(it->contents_);
+ prerender_contents.push_back(it->contents_);
+ }
+ for (std::vector<PrerenderContents*>::iterator it =
+ prerender_contents.begin();
+ it != prerender_contents.end();
+ ++it) {
+ (*it)->DestroyWhenUsingTooManyResources();
}
- std::for_each(prerender_contents.begin(), prerender_contents.end(),
- std::mem_fun(
- &PrerenderContents::DestroyWhenUsingTooManyResources));
DeletePendingDeleteEntries();
}
@@ -1007,20 +986,21 @@ base::TimeDelta PrerenderManager::GetMaxAge() const {
base::TimeDelta::FromSeconds(300) : config_.max_age);
}
-bool PrerenderManager::IsPrerenderFresh(const base::TimeTicks start) const {
+bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const {
DCHECK(CalledOnValidThread());
- return GetCurrentTimeTicks() - start < GetMaxAge();
+ base::Time now = GetCurrentTime();
+ return (now - start < GetMaxAge());
}
void PrerenderManager::DeleteOldEntries() {
DCHECK(CalledOnValidThread());
- while (!active_prerender_list_.empty()) {
- PrerenderContents* contents = active_prerender_list_.front()->contents_;
- DCHECK(contents);
- if (IsPrerenderFresh(contents->load_start_time()))
+ while (!prerender_list_.empty()) {
+ PrerenderContentsData data = prerender_list_.front();
+ if (IsPrerenderElementFresh(data.start_time_))
return;
- contents->Destroy(FINAL_STATUS_TIMED_OUT);
+ data.contents_->Destroy(FINAL_STATUS_TIMED_OUT);
}
+ MaybeStopSchedulingPeriodicCleanups();
}
base::Time PrerenderManager::GetCurrentTime() const {
@@ -1050,53 +1030,58 @@ void PrerenderManager::DeletePendingDeleteEntries() {
}
}
-PrerenderManager::PrerenderData* PrerenderManager::FindPrerenderData(
- const GURL& url,
- const SessionStorageNamespace* session_storage_namespace) {
- for (std::list<linked_ptr<PrerenderData> >::iterator
- it = active_prerender_list_.begin();
- it != active_prerender_list_.end();
+PrerenderManager::PrerenderContentsData* PrerenderManager::FindEntryData(
+ const GURL& url) {
+ DCHECK(CalledOnValidThread());
+ PrerenderContentsDataList::iterator it = FindPrerenderContentsForURL(url);
+ if (it == prerender_list_.end())
+ return NULL;
+ PrerenderContentsData& prerender_contents_data = *it;
+ return &prerender_contents_data;
+}
+
+PrerenderContents* PrerenderManager::FindEntry(const GURL& url) const {
+ DCHECK(CalledOnValidThread());
+ for (PrerenderContentsDataList::const_iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
++it) {
- PrerenderContents* prerender_contents = it->get()->contents_;
- if (prerender_contents->Matches(url, session_storage_namespace))
- return it->get();
+ if (it->contents_->MatchesURL(url, NULL))
+ return it->contents_;
}
+ // Entry not found.
return NULL;
}
-PrerenderManager::PrerenderData*
-PrerenderManager::FindPrerenderDataForChildAndRoute(
- const int child_id, const int route_id) {
- for (std::list<linked_ptr<PrerenderData> >::iterator
- it = active_prerender_list_.begin();
- it != active_prerender_list_.end();
- ++it) {
- PrerenderContents* prerender_contents = it->get()->contents_;
+PrerenderManager::PrerenderContentsDataList::iterator
+ PrerenderManager::FindPrerenderContentsForChildRouteIdPair(
+ const std::pair<int, int>& child_route_id_pair) {
+ PrerenderContentsDataList::iterator it = prerender_list_.begin();
+ for (; it != prerender_list_.end(); ++it) {
+ PrerenderContents* prerender_contents = it->contents_;
- int contents_child_id;
- if (!prerender_contents->GetChildId(&contents_child_id))
- continue;
- int contents_route_id;
- if (!prerender_contents->GetRouteId(&contents_route_id))
- continue;
+ int child_id;
+ int route_id;
+ bool has_child_id = prerender_contents->GetChildId(&child_id);
+ bool has_route_id = has_child_id &&
+ prerender_contents->GetRouteId(&route_id);
- if (contents_child_id == child_id && contents_route_id == route_id)
- return it->get();
+ if (has_child_id && has_route_id &&
+ child_id == child_route_id_pair.first &&
+ route_id == child_route_id_pair.second) {
+ break;
+ }
}
- return NULL;
+ return it;
}
-std::list<linked_ptr<PrerenderManager::PrerenderData> >::iterator
-PrerenderManager::FindIteratorForPrerenderContents(
- PrerenderContents* prerender_contents) {
- for (std::list<linked_ptr<PrerenderData> >::iterator
- it = active_prerender_list_.begin();
- it != active_prerender_list_.end();
- ++it) {
- if (prerender_contents == it->get()->contents_)
+PrerenderManager::PrerenderContentsDataList::iterator
+ PrerenderManager::FindPrerenderContentsForURL(const GURL& url) {
+ for (PrerenderContentsDataList::iterator it = prerender_list_.begin();
+ it != prerender_list_.end(); ++it) {
+ if (it->contents_->MatchesURL(url, NULL))
return it;
}
- return active_prerender_list_.end();
+ return prerender_list_.end();
}
bool PrerenderManager::DoesRateLimitAllowPrerender() const {
@@ -1158,21 +1143,23 @@ void PrerenderManager::AddToHistory(PrerenderContents* contents) {
Value* PrerenderManager::GetActivePrerendersAsValue() const {
ListValue* list_value = new ListValue();
- for (std::list<linked_ptr<PrerenderData> >::const_iterator it =
- active_prerender_list_.begin();
- it != active_prerender_list_.end();
+ for (PrerenderContentsDataList::const_iterator it = prerender_list_.begin();
+ it != prerender_list_.end();
++it) {
- if (Value* prerender_value = it->get()->contents_->GetAsValue())
- list_value->Append(prerender_value);
+ Value* prerender_value = it->contents_->GetAsValue();
+ if (!prerender_value)
+ continue;
+ list_value->Append(prerender_value);
}
return list_value;
}
void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
DeleteOldTabContents();
- while (!active_prerender_list_.empty()) {
- PrerenderContents* contents = active_prerender_list_.front()->contents_;
- contents->Destroy(final_status);
+ while (!prerender_list_.empty()) {
+ PrerenderContentsData data = prerender_list_.front();
+ prerender_list_.pop_front();
+ data.contents_->Destroy(final_status);
}
DeletePendingDeleteEntries();
}
@@ -1231,4 +1218,3 @@ PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
}
} // namespace prerender
-
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 3341572..1a667cc 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -6,7 +6,6 @@
#define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
#include <list>
-#include <map>
#include <string>
#include <utility>
@@ -14,7 +13,6 @@
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
-#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time.h"
@@ -56,7 +54,6 @@ struct hash<content::WebContents*> {
namespace prerender {
class PrerenderCondition;
-class PrerenderHandle;
class PrerenderHistograms;
class PrerenderHistory;
class PrerenderLocalPredictor;
@@ -103,31 +100,36 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// Entry points for adding prerenders.
// Adds a prerender for |url| if valid. |process_id| and |route_id| identify
- // the RenderView that the prerender request came from. If |size| is empty, a
- // default from the PrerenderConfig is used. Returns a caller-owned
- // PrerenderHandle* if the URL was added, NULL if it was not. If the launching
- // RenderView is itself prerendering, the prerender is added as a pending
- // prerender.
- PrerenderHandle* AddPrerenderFromLinkRelPrerender(
+ // the RenderView that the prerender request came from. The |size| may be
+ // empty, and the current tab size will be used if it is. If the current
+ // active tab size cannot be found, we use a default from PrerenderConfig.
+ // Returns true if the URL was added, false if it was not.
+ // If the launching RenderView is itself prerendering, the prerender is added
+ // as a pending prerender.
+ bool AddPrerenderFromLinkRelPrerender(
int process_id,
int route_id,
const GURL& url,
const content::Referrer& referrer,
- const gfx::Size& size);
+ gfx::Size size);
// Adds a prerender for |url| if valid. As the prerender request is coming
// from a source without a RenderViewHost (i.e., the omnibox) we don't have a
// child or route id, or a referrer. This method uses sensible values for
// those. The |session_storage_namespace| matches the namespace of the active
- // tab at the time the prerender is generated from the omnibox. Returns a
- // caller-owned PrerenderHandle*, or NULL.
- PrerenderHandle* AddPrerenderFromOmnibox(
+ // tab at the time the prerender is generated from the omnibox.
+ bool AddPrerenderFromOmnibox(
const GURL& url,
content::SessionStorageNamespace* session_storage_namespace,
- const gfx::Size& size);
+ gfx::Size size);
- // If |process_id| and |view_id| refer to a running prerender, destroy
- // it with |final_status|.
+ // Request cancelation of a previously added prerender. If the |active_count_|
+ // of the prerender is one, it will be canceled. Otherwise, |active_count_|
+ // will be decremented by one.
+ void MaybeCancelPrerender(const GURL& url);
+
+ // Destroy all prerenders for the given child route id pair and assign a final
+ // status to them.
virtual void DestroyPrerenderForRenderView(int process_id,
int view_id,
FinalStatus final_status);
@@ -181,6 +183,10 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// is prerendering a page.
bool IsWebContentsPrerendering(content::WebContents* web_contents) const;
+ // Returns true if there is a prerendered page for the given URL and it has
+ // finished loading. Only valid if called before MaybeUsePrerenderedPage.
+ bool DidPrerenderFinishLoading(const GURL& url) const;
+
// Maintaining and querying the set of WebContents belonging to this
// PrerenderManager that are currently showing prerendered pages.
void MarkWebContentsAsPrerendered(content::WebContents* web_contents);
@@ -230,6 +236,11 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// Adds a condition. This is owned by the PrerenderManager.
void AddCondition(const PrerenderCondition* condition);
+ bool IsPendingEntry(const GURL& url) const;
+
+ // Returns true if |url| matches any URLs being prerendered.
+ bool IsPrerendering(const GURL& url) const;
+
// Records that some visible tab navigated (or was redirected) to the
// provided URL.
void RecordNavigation(const GURL& url);
@@ -239,102 +250,94 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
PrerenderHistograms* histograms() const { return histograms_.get(); }
protected:
- class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
- public:
- // Constructor for a pending prerender, which will get its contents later.
- explicit PrerenderData(PrerenderManager* manager);
-
- // Constructor for an active prerender.
- PrerenderData(PrerenderManager* manager, PrerenderContents* contents);
-
- ~PrerenderData();
-
- // A new PrerenderHandle has been created for this PrerenderData.
- void OnNewHandle();
-
- // The launcher associated with a handle is navigating away from the context
- // that launched this prerender. If the prerender is active, it may stay
- // alive briefly though, in case we we going through a redirect chain that
- // will eventually land at it.
- void OnNavigateAwayByHandle();
-
- // The launcher associated with a handle has taken explicit action to cancel
- // this prerender. We may well destroy the prerender in this case if no
- // other handles continue to track it.
- void OnCancelByHandle();
-
- PrerenderContents* contents() { return contents_; }
-
- private:
- friend class PrerenderManager;
-
- PrerenderManager* manager_;
- PrerenderContents* contents_;
-
- // The number of distinct PrerenderHandles created for |this|, including
- // ones that have called PrerenderData::OnNavigateAwayByHandle(), but not
- // counting the ones that have called PrerenderData::OnCancelByHandle(). For
- // pending prerenders, this will always be 1, since the PrerenderManager
- // only merges handles of running prerenders.
- int handle_count_;
-
- DISALLOW_COPY_AND_ASSIGN(PrerenderData);
- };
-
void SetPrerenderContentsFactory(
PrerenderContents::Factory* prerender_contents_factory);
- // Adds a prerender from a pending Prerender, called by
- // PrerenderContents::StartPendingPrerenders.
- void StartPendingPrerender(
- PrerenderHandle* existing_prerender_handle,
- Origin origin,
- int process_id,
- const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size,
- content::SessionStorageNamespace* session_storage_namespace);
-
- void DestroyPendingPrerenderData(PrerenderData* pending_prerender_data);
-
// Utility method that is called from the virtual Shutdown method on this
// class but is called directly from the TestPrerenderManager in the unit
// tests.
void DoShutdown();
private:
+ // Test that needs needs access to internal functions.
friend class PrerenderBrowserTest;
- friend class PrerenderContents;
- friend class PrerenderHandle;
- friend class UnitTestPrerenderManager;
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, AliasURLTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, CancelAllTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest,
+ CancelOmniboxRemovesOmniboxTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest,
+ CancelOmniboxDoesNotRemoveLinkTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, ClearTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, ControlGroup);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, DropOldestRequestTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, DropSecondRequestTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, ExpireTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, FoundTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, FragmentMatchesFragmentTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, FragmentMatchesPageTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerAbandon);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerAddTwiceAbandonTwice);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerAddTwiceCancelTwice);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest,
+ LinkManagerAddTwiceCancelTwiceThenAbandonTwice);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerCancel);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerCancelThenAbandon);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerCancelThenAddAgain);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerCancelTwice);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerExpireThenAddAgain);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, LinkManagerExpireThenCancel);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, NotSoRecentlyVisited);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, PageMatchesFragmentTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, PendingPrerenderTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, PPLTDummy);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, RateLimitInWindowTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, RateLimitOutsideWindowTest);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, RecentlyVisitedPPLTDummy);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, SourceRenderViewClosed);
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTest, TwoElementPrerenderTest);
+
+ struct PrerenderContentsData;
+ struct NavigationRecord;
class OnCloseTabContentsDeleter;
- struct NavigationRecord;
+ typedef std::list<PrerenderContentsData> PrerenderContentsDataList;
typedef base::hash_map<content::WebContents*, bool> WouldBePrerenderedMap;
// Time window for which we record old navigations, in milliseconds.
static const int kNavigationRecordWindowMs = 5000;
- void OnCancelPrerenderHandle(PrerenderData* prerender_data);
-
- // Adds a prerender for |url| from |referrer| initiated from the process
- // |child_id|. The |origin| specifies how the prerender was added. If |size|
- // is empty, then PrerenderContents::StartPrerendering will instead use a
- // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the
- // caller, or NULL.
- PrerenderHandle* AddPrerender(
+ // Adds a prerender for |url| from referrer |referrer| initiated from the
+ // child process specified by |child_id|. The |origin| specifies how the
+ // prerender was added. If the |size| is empty, then
+ // PrerenderContents::StartPrerendering will instead use the size of the
+ // currently active tab. If the current active tab size cannot be found, it
+ // then uses a default from PrerenderConfig.
+ bool AddPrerender(
Origin origin,
int child_id,
const GURL& url,
const content::Referrer& referrer,
- const gfx::Size& size,
+ gfx::Size size,
content::SessionStorageNamespace* session_storage_namespace);
- void StartSchedulingPeriodicCleanups();
- void StopSchedulingPeriodicCleanups();
+ // Retrieves the PrerenderContents object for the specified URL, if it
+ // has been prerendered. The caller will then have ownership of the
+ // PrerenderContents object and is responsible for freeing it.
+ // Returns NULL if the specified URL has not been prerendered.
+ PrerenderContents* GetEntry(const GURL& url);
- void EvictOldestPrerendersIfNecessary();
+ // Identical to GetEntry, with one exception:
+ // The WebContents specified indicates the WC in which to swap the
+ // prerendering into. If the WebContents specified is the one
+ // to doing the prerendered itself, will return NULL.
+ PrerenderContents* GetEntryButNotSpecifiedWC(const GURL& url,
+ content::WebContents* wc);
+
+ // Starts scheduling periodic cleanups.
+ void StartSchedulingPeriodicCleanups();
+ // Stops scheduling periodic cleanups if they're no longer needed.
+ void MaybeStopSchedulingPeriodicCleanups();
// Deletes stale and cancelled prerendered PrerenderContents, as well as
// WebContents that have been replaced by prerendered WebContents.
@@ -348,7 +351,7 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
void PostCleanupTask();
base::TimeDelta GetMaxAge() const;
- bool IsPrerenderFresh(base::TimeTicks start) const;
+ bool IsPrerenderElementFresh(const base::Time start) const;
void DeleteOldEntries();
virtual base::Time GetCurrentTime() const;
virtual base::TimeTicks GetCurrentTimeTicks() const;
@@ -362,21 +365,20 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// list.
void DeletePendingDeleteEntries();
- // Finds the active PrerenderData object for a running prerender matching
- // |url| and |session_storage_namespace|.
- PrerenderData* FindPrerenderData(
- const GURL& url,
- const content::SessionStorageNamespace* session_storage_namespace);
+ // Finds the specified PrerenderContentsData/PrerenderContents and returns it,
+ // if it exists. Returns NULL otherwise. Unlike GetEntry, the
+ // PrerenderManager maintains ownership of the PrerenderContents.
+ PrerenderContentsData* FindEntryData(const GURL& url);
+ PrerenderContents* FindEntry(const GURL& url) const;
- // If |child_id| and |route_id| correspond to a RenderView that is an active
- // prerender, returns the PrerenderData object for that prerender. Otherwise,
- // returns NULL.
- PrerenderData* FindPrerenderDataForChildAndRoute(int child_id, int route_id);
+ // Returns the iterator to the PrerenderContentsData entry that is being
+ // prerendered from the given child route id pair.
+ PrerenderContentsDataList::iterator
+ FindPrerenderContentsForChildRouteIdPair(
+ const std::pair<int, int>& child_route_id_pair);
- // Given the |prerender_contents|, find the iterator in active_prerender_list_
- // correponding to the given prerender.
- std::list<linked_ptr<PrerenderData> >::iterator
- FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
+ PrerenderContentsDataList::iterator
+ FindPrerenderContentsForURL(const GURL& url);
bool DoesRateLimitAllowPrerender() const;
@@ -437,12 +439,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
PrerenderTracker* prerender_tracker_;
- // List of all running prerenders. It is kept sorted, in increasing order by
- // expiry time. This list owns the PrerenderData objects contained in it.
- std::list<linked_ptr<PrerenderData> > active_prerender_list_;
-
- // List of all pending prerenders.
- std::list<linked_ptr<PrerenderData> > pending_prerender_list_;
+ // List of prerendered elements.
+ PrerenderContentsDataList prerender_list_;
// List of recent navigations in this profile, sorted by ascending
// navigate_time_.
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 5a17ee0..b6403d9 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -7,7 +7,6 @@
#include "base/message_loop.h"
#include "base/time.h"
#include "chrome/browser/prerender/prerender_contents.h"
-#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_link_manager.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_origin.h"
@@ -25,17 +24,20 @@ using content::Referrer;
namespace prerender {
-class UnitTestPrerenderManager;
-
namespace {
class DummyPrerenderContents : public PrerenderContents {
public:
- DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager,
+ DummyPrerenderContents(PrerenderManager* prerender_manager,
PrerenderTracker* prerender_tracker,
const GURL& url,
Origin origin,
- FinalStatus expected_final_status);
+ FinalStatus expected_final_status)
+ : PrerenderContents(prerender_manager, prerender_tracker,
+ NULL, url, Referrer(), origin,
+ PrerenderManager::kNoExperiment),
+ expected_final_status_(expected_final_status) {
+ }
virtual ~DummyPrerenderContents() {
EXPECT_EQ(expected_final_status_, final_status());
@@ -45,7 +47,14 @@ class DummyPrerenderContents : public PrerenderContents {
int ALLOW_UNUSED creator_child_id,
const gfx::Size& ALLOW_UNUSED size,
content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace,
- bool is_control_group) OVERRIDE;
+ bool is_control_group) OVERRIDE {
+ // In the base PrerenderContents implementation, StartPrerendering will
+ // be called even when the PrerenderManager is part of the control group,
+ // but it will early exit before actually creating a new RenderView if
+ // |is_control_group| is true;
+ if (!is_control_group)
+ prerendering_has_started_ = true;
+ }
virtual bool GetChildId(int* child_id) const OVERRIDE {
*child_id = 0;
@@ -64,20 +73,12 @@ class DummyPrerenderContents : public PrerenderContents {
}
private:
- UnitTestPrerenderManager* test_prerender_manager_;
FinalStatus expected_final_status_;
};
-const gfx::Size kSize(640, 480);
-
-} // namespace
-
-class UnitTestPrerenderManager : public PrerenderManager {
+class TestPrerenderManager : public PrerenderManager {
public:
- using PrerenderManager::kNavigationRecordWindowMs;
- using PrerenderManager::GetMaxAge;
-
- explicit UnitTestPrerenderManager(PrerenderTracker* prerender_tracker)
+ explicit TestPrerenderManager(PrerenderTracker* prerender_tracker)
: PrerenderManager(&profile_, prerender_tracker),
time_(base::Time::Now()),
time_ticks_(base::TimeTicks::Now()),
@@ -86,36 +87,23 @@ class UnitTestPrerenderManager : public PrerenderManager {
set_rate_limit_enabled(false);
}
- virtual ~UnitTestPrerenderManager() {
+ virtual ~TestPrerenderManager() {
if (next_prerender_contents()) {
next_prerender_contents_.release()->Destroy(
FINAL_STATUS_MANAGER_SHUTDOWN);
}
+ // Set the final status for all PrerenderContents with an expected final
+ // status of FINAL_STATUS_USED. These values are normally set when the
+ // prerendered RVH is swapped into a tab, which doesn't happen in these
+ // unit tests.
+ for (ScopedVector<PrerenderContents>::iterator it =
+ used_prerender_contents_.begin();
+ it != used_prerender_contents_.end(); ++it) {
+ (*it)->set_final_status(FINAL_STATUS_USED);
+ }
DoShutdown();
}
- PrerenderContents* FindEntry(const GURL& url) {
- DeleteOldEntries();
- DeletePendingDeleteEntries();
- if (PrerenderData* data = FindPrerenderData(url, NULL))
- return data->contents();
- return NULL;
- }
-
- PrerenderContents* FindAndUseEntry(const GURL& url) {
- PrerenderData* prerender_data = FindPrerenderData(url, NULL);
- if (!prerender_data)
- return NULL;
- PrerenderContents* prerender_contents = prerender_data->contents();
- prerender_contents->set_final_status(FINAL_STATUS_USED);
- std::list<linked_ptr<PrerenderData> >::iterator to_erase =
- FindIteratorForPrerenderContents(prerender_contents);
- DCHECK(to_erase != active_prerender_list_.end());
- active_prerender_list_.erase(to_erase);
- prerender_contents->StartPendingPrerenders();
- return prerender_contents;
- }
-
void AdvanceTime(base::TimeDelta delta) {
time_ += delta;
}
@@ -171,15 +159,6 @@ class UnitTestPrerenderManager : public PrerenderManager {
return next_prerender_contents_.get();
}
- // from PrerenderManager
- virtual base::Time GetCurrentTime() const OVERRIDE {
- return time_;
- }
-
- virtual base::TimeTicks GetCurrentTimeTicks() const OVERRIDE {
- return time_ticks_;
- }
-
private:
void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
DCHECK(!next_prerender_contents_.get());
@@ -188,6 +167,13 @@ class UnitTestPrerenderManager : public PrerenderManager {
used_prerender_contents_.push_back(prerender_contents);
}
+ virtual base::Time GetCurrentTime() const OVERRIDE {
+ return time_;
+ }
+
+ virtual base::TimeTicks GetCurrentTimeTicks() const OVERRIDE {
+ return time_ticks_;
+ }
virtual PrerenderContents* CreatePrerenderContents(
const GURL& url,
@@ -195,8 +181,8 @@ class UnitTestPrerenderManager : public PrerenderManager {
Origin origin,
uint8 experiment_id) OVERRIDE {
DCHECK(next_prerender_contents_.get());
- EXPECT_EQ(url, next_prerender_contents_->prerender_url());
- EXPECT_EQ(origin, next_prerender_contents_->origin());
+ DCHECK_EQ(next_prerender_contents_->prerender_url(), url);
+ DCHECK_EQ(next_prerender_contents_->origin(), origin);
return next_prerender_contents_.release();
}
@@ -222,32 +208,7 @@ class RestorePrerenderMode {
PrerenderManager::PrerenderManagerMode prev_mode_;
};
-DummyPrerenderContents::DummyPrerenderContents(
- UnitTestPrerenderManager* test_prerender_manager,
- PrerenderTracker* prerender_tracker,
- const GURL& url,
- Origin origin,
- FinalStatus expected_final_status)
- : PrerenderContents(test_prerender_manager, prerender_tracker,
- NULL, url, Referrer(), origin,
- PrerenderManager::kNoExperiment),
- test_prerender_manager_(test_prerender_manager),
- expected_final_status_(expected_final_status) {
-}
-
-void DummyPrerenderContents::StartPrerendering(
- int ALLOW_UNUSED creator_child_id,
- const gfx::Size& ALLOW_UNUSED size,
- content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace,
- bool is_control_group) {
- // In the base PrerenderContents implementation, StartPrerendering will
- // be called even when the PrerenderManager is part of the control group,
- // but it will early exit before actually creating a new RenderView if
- // |is_control_group| is true;
- if (!is_control_group)
- prerendering_has_started_ = true;
- load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
-}
+} // namespace
class PrerenderTest : public testing::Test {
public:
@@ -256,7 +217,7 @@ class PrerenderTest : public testing::Test {
PrerenderTest() : ui_thread_(BrowserThread::UI, &message_loop_),
prerender_manager_(
- new UnitTestPrerenderManager(prerender_tracker())),
+ new TestPrerenderManager(prerender_tracker())),
prerender_link_manager_(
new PrerenderLinkManager(prerender_manager_.get())),
last_prerender_id_(0) {
@@ -266,11 +227,7 @@ class PrerenderTest : public testing::Test {
switches::kPrerenderFromOmniboxSwitchValueEnabled);
}
- ~PrerenderTest() {
- prerender_link_manager_->OnChannelClosing(kDefaultChildId);
- }
-
- UnitTestPrerenderManager* prerender_manager() {
+ TestPrerenderManager* prerender_manager() {
return prerender_manager_.get();
}
@@ -295,7 +252,7 @@ class PrerenderTest : public testing::Test {
return prerender_link_manager()->OnAddPrerender(
kDefaultChildId, GetNextPrerenderID(),
url, content::Referrer(),
- kSize, kDefaultRenderViewRouteId);
+ gfx::Size(), kDefaultRenderViewRouteId);
}
private:
@@ -306,23 +263,18 @@ class PrerenderTest : public testing::Test {
// Needed to pass PrerenderManager's DCHECKs.
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
- scoped_ptr<UnitTestPrerenderManager> prerender_manager_;
+ scoped_ptr<TestPrerenderManager> prerender_manager_;
scoped_ptr<PrerenderLinkManager> prerender_link_manager_;
int last_prerender_id_;
};
-TEST_F(PrerenderTest, FoundTest) {
- GURL url("http://www.google.com/");
- DummyPrerenderContents* prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- url,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url));
- EXPECT_TRUE(prerender_contents->prerendering_has_started());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+TEST_F(PrerenderTest, EmptyTest) {
+ EXPECT_FALSE(prerender_manager()->MaybeUsePrerenderedPage(
+ NULL,
+ GURL("http://www.google.com/")));
}
-TEST_F(PrerenderTest, DuplicateTest) {
+TEST_F(PrerenderTest, FoundTest) {
GURL url("http://www.google.com/");
DummyPrerenderContents* prerender_contents =
prerender_manager()->CreateNextPrerenderContents(
@@ -330,19 +282,7 @@ TEST_F(PrerenderTest, DuplicateTest) {
FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
- scoped_ptr<PrerenderHandle> duplicate_prerender_handle(
- prerender_manager()->AddPrerenderFromLinkRelPrerender(
- kDefaultChildId, kDefaultRenderViewRouteId, url,
- Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
-
- EXPECT_TRUE(duplicate_prerender_handle->IsValid());
- EXPECT_TRUE(duplicate_prerender_handle->IsPrerendering());
-
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
-
- EXPECT_FALSE(duplicate_prerender_handle->IsValid());
- EXPECT_FALSE(duplicate_prerender_handle->IsPrerendering());
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// Make sure that if queue a request, and a second prerender request for the
@@ -367,7 +307,7 @@ TEST_F(PrerenderTest, DropSecondRequestTest) {
prerender_manager()->next_prerender_contents());
EXPECT_FALSE(prerender_contents1->prerendering_has_started());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// Ensure that we expire a prerendered page after the max. permitted time.
@@ -381,9 +321,9 @@ TEST_F(PrerenderTest, ExpireTest) {
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
EXPECT_TRUE(prerender_contents->prerendering_has_started());
- prerender_manager()->AdvanceTimeTicks(prerender_manager()->GetMaxAge() +
- base::TimeDelta::FromSeconds(1));
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ prerender_manager()->AdvanceTime(prerender_manager()->GetMaxAge() +
+ base::TimeDelta::FromSeconds(1));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
}
// LRU Test. Make sure that if we prerender more than one request, that
@@ -408,8 +348,8 @@ TEST_F(PrerenderTest, DropOldestRequestTest) {
EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
EXPECT_TRUE(prerender_contents1->prerendering_has_started());
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
- ASSERT_EQ(prerender_contents1, prerender_manager()->FindAndUseEntry(url1));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
+ ASSERT_EQ(prerender_contents1, prerender_manager()->GetEntry(url1));
}
// Two element prerender test. Ensure that the LRU operates correctly if we
@@ -444,9 +384,9 @@ TEST_F(PrerenderTest, TwoElementPrerenderTest) {
EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
EXPECT_TRUE(prerender_contents2->prerendering_has_started());
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
- ASSERT_EQ(prerender_contents1, prerender_manager()->FindAndUseEntry(url1));
- ASSERT_EQ(prerender_contents2, prerender_manager()->FindAndUseEntry(url2));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
+ ASSERT_EQ(prerender_contents1, prerender_manager()->GetEntry(url1));
+ ASSERT_EQ(prerender_contents2, prerender_manager()->GetEntry(url2));
}
TEST_F(PrerenderTest, AliasURLTest) {
@@ -463,18 +403,16 @@ TEST_F(PrerenderTest, AliasURLTest) {
prerender_manager()->CreateNextPrerenderContents(
url, alias_urls, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
- ASSERT_EQ(NULL, prerender_manager()->FindEntry(not_an_alias_url));
- ASSERT_EQ(prerender_contents,
- prerender_manager()->FindAndUseEntry(alias_url1));
+ ASSERT_EQ(NULL, prerender_manager()->GetEntry(not_an_alias_url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(alias_url1));
prerender_contents = prerender_manager()->CreateNextPrerenderContents(
url, alias_urls, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
- ASSERT_EQ(prerender_contents,
- prerender_manager()->FindAndUseEntry(alias_url2));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(alias_url2));
prerender_contents = prerender_manager()->CreateNextPrerenderContents(
url, alias_urls, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
// Test that alias URLs can not be added.
prerender_contents = prerender_manager()->CreateNextPrerenderContents(
@@ -483,7 +421,7 @@ TEST_F(PrerenderTest, AliasURLTest) {
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(AddSimplePrerender(alias_url1));
EXPECT_TRUE(AddSimplePrerender(alias_url2));
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// Ensure that we ignore prerender requests within the rate limit.
@@ -551,92 +489,14 @@ TEST_F(PrerenderTest, PendingPrerenderTest) {
GURL pending_url("http://news.google.com/");
- DummyPrerenderContents* pending_prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- pending_url,
- ORIGIN_GWS_PRERENDER,
- FINAL_STATUS_USED);
- scoped_ptr<PrerenderHandle> pending_prerender_handle(
- prerender_manager()->AddPrerenderFromLinkRelPrerender(
- child_id, route_id, pending_url,
- Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
- DCHECK(pending_prerender_handle.get());
- EXPECT_TRUE(pending_prerender_handle->IsValid());
- EXPECT_TRUE(pending_prerender_handle->IsPending());
+ EXPECT_TRUE(prerender_manager()->AddPrerenderFromLinkRelPrerender(
+ child_id, route_id,
+ pending_url, Referrer(url, WebKit::WebReferrerPolicyDefault),
+ gfx::Size()));
+ EXPECT_TRUE(prerender_manager()->IsPendingEntry(pending_url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
-
- EXPECT_FALSE(pending_prerender_handle->IsPending());
- ASSERT_EQ(pending_prerender_contents,
- prerender_manager()->FindAndUseEntry(pending_url));
-}
-
-TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
- GURL url("http://www.google.com/");
- DummyPrerenderContents* prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- url,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url));
-
- int child_id;
- int route_id;
- ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
- ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
-
- // This pending URL has an unsupported scheme, and won't be able
- // to start.
- GURL pending_url("ftp://news.google.com/");
-
- prerender_manager()->CreateNextPrerenderContents(
- pending_url,
- ORIGIN_GWS_PRERENDER,
- FINAL_STATUS_UNSUPPORTED_SCHEME);
- scoped_ptr<PrerenderHandle> pending_prerender_handle(
- prerender_manager()->AddPrerenderFromLinkRelPrerender(
- child_id, route_id, pending_url,
- Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
- DCHECK(pending_prerender_handle.get());
- EXPECT_TRUE(pending_prerender_handle->IsValid());
- EXPECT_TRUE(pending_prerender_handle->IsPending());
-
- EXPECT_TRUE(prerender_contents->prerendering_has_started());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
-
- EXPECT_FALSE(pending_prerender_handle->IsValid());
- EXPECT_FALSE(pending_prerender_handle->IsPending());
-}
-
-TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
- GURL url("http://www.google.com/");
- DummyPrerenderContents* prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- url,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url));
-
- int child_id;
- int route_id;
- ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
- ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
-
- GURL pending_url("http://news.google.com/");
-
- scoped_ptr<PrerenderHandle> pending_prerender_handle(
- prerender_manager()->AddPrerenderFromLinkRelPrerender(
- child_id, route_id, pending_url,
- Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
- DCHECK(pending_prerender_handle.get());
- EXPECT_TRUE(pending_prerender_handle->IsValid());
- EXPECT_TRUE(pending_prerender_handle->IsPending());
-
- EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
- pending_prerender_handle->OnCancel();
- EXPECT_FALSE(pending_prerender_handle->IsValid());
-
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// Tests that a PrerenderManager created for a browser session in the control
@@ -664,7 +524,7 @@ TEST_F(PrerenderTest, SourceRenderViewClosed) {
FINAL_STATUS_MANAGER_SHUTDOWN);
EXPECT_FALSE(prerender_link_manager()->OnAddPrerender(
100, GetNextPrerenderID(), url,
- Referrer(), kSize, 200));
+ Referrer(), gfx::Size(), 200));
}
// Tests that prerendering is cancelled when we launch a second prerender of
@@ -687,14 +547,14 @@ TEST_F(PrerenderTest, NotSoRecentlyVisited) {
prerender_manager()->RecordNavigation(url);
prerender_manager()->AdvanceTimeTicks(
base::TimeDelta::FromMilliseconds(
- UnitTestPrerenderManager::kNavigationRecordWindowMs + 500));
+ PrerenderManager::kNavigationRecordWindowMs + 500));
DummyPrerenderContents* prerender_contents =
prerender_manager()->CreateNextPrerenderContents(
url, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// Tests that our PPLT dummy prerender gets created properly.
@@ -713,7 +573,7 @@ TEST_F(PrerenderTest, PPLTDummy) {
// Adding this ftp URL will force the expected unsupported scheme error.
prerender_contents->AddAliasURL(ftp_url);
- ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(pplt_dummy_contents, prerender_manager()->GetEntry(url));
}
// Tests that our PPLT dummy prerender gets created properly, even
@@ -733,29 +593,29 @@ TEST_F(PrerenderTest, RecentlyVisitedPPLTDummy) {
GURL ftp_url("ftp://ftp.google.com/");
prerender_contents->AddAliasURL(ftp_url);
- ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(pplt_dummy_contents, prerender_manager()->GetEntry(url));
}
-// Tests that the prerender link manager discards fragments when launching,
-// and matches only occur on URLs without fragments.
-// TODO(gavinp): Drop this test once we are fragment clean.
-TEST_F(PrerenderTest, FragmentDroppedOnLaunchTest) {
- GURL fragment_url("http://www.google.com/#test");
+// Tests that the prerender manager ignores fragment references when matching
+// prerender URLs in the case the fragment is not in the prerender URL.
+TEST_F(PrerenderTest, PageMatchesFragmentTest) {
GURL url("http://www.google.com/");
+ GURL fragment_url("http://www.google.com/#test");
DummyPrerenderContents* prerender_contents =
prerender_manager()->CreateNextPrerenderContents(url,
FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(fragment_url));
+ EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
- EXPECT_FALSE(prerender_manager()->FindEntry(fragment_url));
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(fragment_url));
}
-// Tests that the prerender manager matches include the fragment.
-// TODO(gavinp): Re-enable this once we are fragment clean.
+// Tests that the prerender manager ignores fragment references when matching
+// prerender URLs in the case the fragment is in the prerender URL.
+// TODO(gavinp): Re-enable this in the Prerender API once we're officially
// fragment clean.
-TEST_F(PrerenderTest, DISABLED_FragmentMatchesTest) {
+TEST_F(PrerenderTest, DISABLED_FragmentMatchesPageTest) {
+ GURL url("http://www.google.com/");
GURL fragment_url("http://www.google.com/#test");
DummyPrerenderContents* prerender_contents =
@@ -763,14 +623,14 @@ TEST_F(PrerenderTest, DISABLED_FragmentMatchesTest) {
FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(fragment_url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
- ASSERT_EQ(prerender_contents,
- prerender_manager()->FindAndUseEntry(fragment_url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
-// Tests that the prerender manager uses fragment references when matching
-// prerender URLs in the case a different fragment is in both URLs.
-// TODO(gavinp): Re-enable this once we are fragment clean.
-TEST_F(PrerenderTest, DISABLED_FragmentsDifferTest) {
+// Tests that the prerender manager ignores fragment references when matching
+// prerender URLs in the case the fragment is in both URLs.
+// TODO(gavinp): Re-enable this in the Prerender API once we're officially
+// fragment clean.
+TEST_F(PrerenderTest, DISABLED_FragmentMatchesFragmentTest) {
GURL fragment_url("http://www.google.com/#test");
GURL other_fragment_url("http://www.google.com/#other_test");
@@ -779,12 +639,8 @@ TEST_F(PrerenderTest, DISABLED_FragmentsDifferTest) {
FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(fragment_url));
EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
- DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url));
-
ASSERT_EQ(prerender_contents,
- prerender_manager()->FindAndUseEntry(fragment_url));
+ prerender_manager()->GetEntry(other_fragment_url));
}
// Make sure that clearing works as expected.
@@ -844,7 +700,7 @@ TEST_F(PrerenderTest, LinkManagerCancel) {
EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
}
@@ -872,10 +728,10 @@ TEST_F(PrerenderTest, LinkManagerCancelThenAbandon) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
}
-// TODO(gavinp): Re-enabmed this test after abandon has an effect on Prerenders,
+// TODO(gavinp): Update this test after abandon has an effect on Prerenders,
// like shortening the timeouts.
TEST_F(PrerenderTest, LinkManagerAbandon) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
@@ -894,7 +750,7 @@ TEST_F(PrerenderTest, LinkManagerAbandon) {
last_prerender_id());
EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
}
@@ -915,7 +771,7 @@ TEST_F(PrerenderTest, LinkManagerCancelTwice) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
last_prerender_id());
}
@@ -950,7 +806,7 @@ TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwice) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
}
TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) {
@@ -993,7 +849,7 @@ TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
}
// TODO(gavinp): Update this test after abandon has an effect on Prerenders,
@@ -1027,7 +883,7 @@ TEST_F(PrerenderTest, LinkManagerAddTwiceAbandonTwice) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
- ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(prerender_contents, prerender_manager()->GetEntry(url));
}
// TODO(gavinp): After abandon shortens the expire time on a Prerender,
@@ -1046,17 +902,17 @@ TEST_F(PrerenderTest, LinkManagerExpireThenCancel) {
EXPECT_TRUE(prerender_contents->prerendering_has_started());
EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
- prerender_manager()->AdvanceTimeTicks(prerender_manager()->GetMaxAge() +
- base::TimeDelta::FromSeconds(1));
+ prerender_manager()->AdvanceTime(prerender_manager()->GetMaxAge() +
+ base::TimeDelta::FromSeconds(1));
EXPECT_FALSE(IsEmptyPrerenderLinkManager());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
last_prerender_id());
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
}
TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) {
@@ -1068,19 +924,17 @@ TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) {
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
- ASSERT_EQ(first_prerender_contents,
- prerender_manager()->FindAndUseEntry(url));
- prerender_manager()->AdvanceTimeTicks(prerender_manager()->GetMaxAge() +
- base::TimeDelta::FromSeconds(1));
+ ASSERT_EQ(first_prerender_contents, prerender_manager()->FindEntry(url));
+ prerender_manager()->AdvanceTime(prerender_manager()->GetMaxAge() +
+ base::TimeDelta::FromSeconds(1));
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
DummyPrerenderContents* second_prerender_contents =
prerender_manager()->CreateNextPrerenderContents(
url, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
- ASSERT_EQ(second_prerender_contents,
- prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(second_prerender_contents, prerender_manager()->GetEntry(url));
// The PrerenderLinkManager is not empty since we never removed the first
// prerender.
EXPECT_FALSE(IsEmptyPrerenderLinkManager());
@@ -1101,14 +955,13 @@ TEST_F(PrerenderTest, LinkManagerCancelThenAddAgain) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
EXPECT_TRUE(first_prerender_contents->prerendering_has_been_cancelled());
DummyPrerenderContents* null = NULL;
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
+ ASSERT_EQ(null, prerender_manager()->GetEntry(url));
DummyPrerenderContents* second_prerender_contents =
prerender_manager()->CreateNextPrerenderContents(
url, FINAL_STATUS_USED);
EXPECT_TRUE(AddSimplePrerender(url));
EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
- ASSERT_EQ(second_prerender_contents,
- prerender_manager()->FindAndUseEntry(url));
+ ASSERT_EQ(second_prerender_contents, prerender_manager()->GetEntry(url));
EXPECT_FALSE(IsEmptyPrerenderLinkManager());
}
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
index 51282ac..5661042 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
@@ -1122,13 +1122,18 @@ void OmniboxEditModel::DoPrerender(const AutocompleteMatch& match) {
TabContents* tab = controller_->GetTabContents();
if (!tab)
return;
+ prerender::PrerenderManager* prerender_manager =
+ prerender::PrerenderManagerFactory::GetForProfile(tab->profile());
+ if (!prerender_manager)
+ return;
+
+ content::RenderViewHost* current_host =
+ tab->web_contents()->GetRenderViewHost();
gfx::Rect container_bounds;
tab->web_contents()->GetView()->GetContainerBounds(&container_bounds);
- AutocompleteActionPredictorFactory::GetForProfile(profile_)->
- StartPrerendering(match.destination_url,
- tab->web_contents()->GetRenderViewHost()->
- GetSessionStorageNamespace(),
- container_bounds.size());
+ prerender_manager->AddPrerenderFromOmnibox(
+ match.destination_url, current_host->GetSessionStorageNamespace(),
+ container_bounds.size());
}
void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index dc0426f..b001200 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1798,8 +1798,6 @@
'browser/prerender/prerender_field_trial.h',
'browser/prerender/prerender_final_status.cc',
'browser/prerender/prerender_final_status.h',
- 'browser/prerender/prerender_handle.cc',
- 'browser/prerender/prerender_handle.h',
'browser/prerender/prerender_histograms.cc',
'browser/prerender/prerender_histograms.h',
'browser/prerender/prerender_history.cc',