summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authordominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-25 19:03:27 +0000
committerdominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-25 19:03:27 +0000
commit1459fb6d13c6e8da1fd72a569e9410a1d038bd59 (patch)
tree869478ccf95444e29cffb9e5e70acc0015379057 /chrome/browser
parent8b001f3e36a29f590e57d46e8e1b357685eb38c1 (diff)
downloadchromium_src-1459fb6d13c6e8da1fd72a569e9410a1d038bd59.zip
chromium_src-1459fb6d13c6e8da1fd72a569e9410a1d038bd59.tar.gz
chromium_src-1459fb6d13c6e8da1fd72a569e9410a1d038bd59.tar.bz2
Remove a chrome dependency by removing Prerender from ResourceDispatcherHost.
BUG=82590,77090 TEST=Prerender* Review URL: http://codereview.chromium.org/6966017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86667 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser_process.h6
-rw-r--r--chrome/browser/browser_process_impl.cc14
-rw-r--r--chrome/browser/browser_process_impl.h10
-rw-r--r--chrome/browser/prerender/prerender_browsertest.cc8
-rw-r--r--chrome/browser/prerender/prerender_contents.cc37
-rw-r--r--chrome/browser/prerender/prerender_contents.h8
-rw-r--r--chrome/browser/prerender/prerender_manager.cc11
-rw-r--r--chrome/browser/prerender/prerender_manager.h12
-rw-r--r--chrome/browser/prerender/prerender_manager_unittest.cc28
-rw-r--r--chrome/browser/prerender/prerender_tracker.cc64
-rw-r--r--chrome/browser/prerender/prerender_tracker.h22
-rw-r--r--chrome/browser/prerender/prerender_tracker_unittest.cc9
-rw-r--r--chrome/browser/profiles/profile_impl.cc8
-rw-r--r--chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc79
-rw-r--r--chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h43
15 files changed, 271 insertions, 88 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 1bd5737..e1944bd 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -58,6 +58,10 @@ namespace net {
class URLRequestContextGetter;
}
+namespace prerender {
+class PrerenderTracker;
+}
+
namespace printing {
class BackgroundPrintingManager;
class PrintJobManager;
@@ -221,6 +225,8 @@ class BrowserProcess {
virtual ChromeNetLog* net_log() = 0;
+ virtual prerender::PrerenderTracker* prerender_tracker() = 0;
+
#if defined(IPC_MESSAGE_LOG_ENABLED)
// Enable or disable IPC logging for the browser, all processes
// derived from ChildProcess (plugin etc), and all
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 51dc452..481fa18 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -45,10 +45,12 @@
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_tab_controller.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h"
#include "chrome/browser/safe_browsing/client_side_detection_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/shell_integration.h"
@@ -694,6 +696,13 @@ ChromeNetLog* BrowserProcessImpl::net_log() {
return net_log_.get();
}
+prerender::PrerenderTracker* BrowserProcessImpl::prerender_tracker() {
+ if (!prerender_tracker_.get())
+ prerender_tracker_.reset(new prerender::PrerenderTracker);
+
+ return prerender_tracker_.get();
+}
+
void BrowserProcessImpl::ClearLocalState(const FilePath& profile_path) {
webkit_database::DatabaseTracker::ClearLocalState(profile_path);
BrowsingDataRemover::ClearGearsData(profile_path);
@@ -730,6 +739,11 @@ void BrowserProcessImpl::CreateResourceDispatcherHost() {
resource_dispatcher_host_.reset(
new ResourceDispatcherHost(resource_queue_delegates));
resource_dispatcher_host_->Initialize();
+
+ resource_dispatcher_host_observer_.reset(
+ new ChromeResourceDispatcherHostObserver(prerender_tracker()));
+ resource_dispatcher_host_->set_observer(
+ resource_dispatcher_host_observer_.get());
}
void BrowserProcessImpl::CreateMetricsService() {
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 577d4ba..eb8a9b6 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -28,6 +28,7 @@
#include "ipc/ipc_message.h"
class ChromeNetLog;
+class ChromeResourceDispatcherHostObserver;
class CommandLine;
class DevToolsHttpProtocolHandler;
class DevToolsProtocolHandler;
@@ -111,6 +112,8 @@ class BrowserProcessImpl : public BrowserProcess,
virtual ChromeNetLog* net_log();
+ virtual prerender::PrerenderTracker* prerender_tracker();
+
#if defined(IPC_MESSAGE_LOG_ENABLED)
virtual void SetIPCLoggingEnabled(bool enable);
#endif
@@ -276,6 +279,13 @@ class BrowserProcessImpl : public BrowserProcess,
// Lives here so can safely log events on shutdown.
scoped_ptr<ChromeNetLog> net_log_;
+ // Ordered before resource_dispatcher_host_observer_ due to destruction
+ // ordering.
+ scoped_ptr<prerender::PrerenderTracker> prerender_tracker_;
+
+ scoped_ptr<ChromeResourceDispatcherHostObserver>
+ resource_dispatcher_host_observer_;
+
NotificationRegistrar notification_registrar_;
scoped_refptr<PluginDataRemover> plugin_data_remover_;
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index e91ef0d..de033b5 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -70,12 +70,14 @@ class TestPrerenderContents : public PrerenderContents {
public:
TestPrerenderContents(
PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
Profile* profile,
const GURL& url,
const GURL& referrer,
int number_of_loads,
FinalStatus expected_final_status)
- : PrerenderContents(prerender_manager, profile, url, referrer),
+ : PrerenderContents(prerender_manager, prerender_tracker, profile,
+ url, referrer),
number_of_loads_(0),
expected_number_of_loads_(number_of_loads),
expected_final_status_(expected_final_status),
@@ -203,6 +205,7 @@ class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
virtual PrerenderContents* CreatePrerenderContents(
PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
Profile* profile,
const GURL& url,
const GURL& referrer) OVERRIDE {
@@ -214,7 +217,8 @@ class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
VLOG(1) << "Creating prerender contents for " << url.path() <<
" with expected final status " << expected_final_status;
VLOG(1) << expected_final_status_queue_.size() << " left in the queue.";
- return new TestPrerenderContents(prerender_manager, profile, url,
+ return new TestPrerenderContents(prerender_manager, prerender_tracker,
+ profile, url,
referrer, number_of_loads_,
expected_final_status);
}
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index b514478..b5015ff 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -32,6 +32,7 @@
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/renderer_host/resource_request_details.h"
+#include "content/browser/resource_context.h"
#include "content/browser/site_instance.h"
#include "content/browser/tab_contents/tab_contents_delegate.h"
#include "content/browser/tab_contents/tab_contents_view.h"
@@ -69,9 +70,10 @@ struct PrerenderUrlPredicate {
class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
public:
virtual PrerenderContents* CreatePrerenderContents(
- PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
- const GURL& referrer) OVERRIDE {
- return new PrerenderContents(prerender_manager, profile, url, referrer);
+ PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker,
+ Profile* profile, const GURL& url, const GURL& referrer) OVERRIDE {
+ return new PrerenderContents(prerender_manager, prerender_tracker, profile,
+ url, referrer);
}
};
@@ -125,10 +127,12 @@ class PrerenderContents::TabContentsDelegateImpl
};
PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
Profile* profile,
const GURL& url,
const GURL& referrer)
: prerender_manager_(prerender_manager),
+ prerender_tracker_(prerender_tracker),
render_view_host_(NULL),
prerender_url_(url),
referrer_(referrer),
@@ -188,8 +192,10 @@ void PrerenderContents::StartPrerenderingOld(
// Register this with the PrerenderTracker as a prerendering RenderViewHost.
// This must be done before the Navigate message to catch all resource
// requests.
- PrerenderTracker::GetInstance()->OnPrerenderingStarted(child_id_, route_id_,
- prerender_manager_);
+ prerender_tracker_->OnPrerenderingStarted(
+ child_id_,
+ route_id_,
+ prerender_manager_);
// Close ourselves when the application is shutting down.
notification_registrar_.Add(this, NotificationType::APP_TERMINATING,
@@ -292,8 +298,10 @@ void PrerenderContents::StartPrerendering(
// RenderViewHost. This must be done before the Navigate message to catch all
// resource requests, but as it is on the same thread as the Navigate message
// (IO) there is no race condition.
- PrerenderTracker::GetInstance()->OnPrerenderingStarted(child_id_, route_id_,
- prerender_manager_);
+ prerender_tracker_->OnPrerenderingStarted(
+ child_id_,
+ route_id_,
+ prerender_manager_);
// Close ourselves when the application is shutting down.
notification_registrar_.Add(this, NotificationType::APP_TERMINATING,
@@ -381,10 +389,8 @@ PrerenderContents::~PrerenderContents() {
if (render_view_host_)
render_view_host_->Shutdown();
- if (child_id_ != -1 && route_id_ != -1) {
- PrerenderTracker::GetInstance()->OnPrerenderingFinished(
- child_id_, route_id_);
- }
+ if (child_id_ != -1 && route_id_ != -1)
+ prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_);
// If we still have a TabContents, clean up anything we need to and then
// destroy it.
@@ -728,15 +734,14 @@ void PrerenderContents::Destroy(FinalStatus final_status) {
// because destroy may be called directly from the UI thread without calling
// TryCancel(). This is difficult to completely avoid, since prerendering
// can be cancelled before a RenderView is created.
- bool is_cancelled =
- PrerenderTracker::GetInstance()->TryCancel(child_id_, route_id_,
- final_status);
+ bool is_cancelled = prerender_tracker_->TryCancel(
+ child_id_, route_id_, final_status);
CHECK(is_cancelled);
// A different final status may have been set already from another thread.
// If so, use it instead.
- if (!PrerenderTracker::GetInstance()->GetFinalStatus(child_id_, route_id_,
- &final_status)) {
+ if (!prerender_tracker_->GetFinalStatus(child_id_, route_id_,
+ &final_status)) {
NOTREACHED();
}
}
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index eeb6101..4a9108b 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -40,6 +40,7 @@ class Rect;
namespace prerender {
class PrerenderManager;
+class PrerenderTracker;
// This class is a peer of TabContents. It can host a renderer, but does not
// have any visible display. Its navigation is not managed by a
@@ -62,8 +63,11 @@ class PrerenderContents : public RenderViewHostDelegate,
Factory() {}
virtual ~Factory() {}
+ // Ownership is not transfered through this interface as prerender_manager,
+ // prerender_tracker, and profile are stored as weak pointers.
virtual PrerenderContents* CreatePrerenderContents(
PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
Profile* profile,
const GURL& url,
const GURL& referrer) = 0;
@@ -258,6 +262,7 @@ class PrerenderContents : public RenderViewHostDelegate,
protected:
PrerenderContents(PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
Profile* profile,
const GURL& url,
const GURL& referrer);
@@ -296,6 +301,9 @@ class PrerenderContents : public RenderViewHostDelegate,
// The prerender manager owning this object.
PrerenderManager* prerender_manager_;
+ // The prerender tracker tracking prerenders.
+ PrerenderTracker* prerender_tracker_;
+
// The host for our HTML content.
RenderViewHost* render_view_host_;
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 7f3dd2b..969c564 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -11,6 +11,7 @@
#include "base/metrics/histogram.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_final_status.h"
@@ -206,10 +207,12 @@ void DestroyPreloadForRenderView(
final_status);
}
-PrerenderManager::PrerenderManager(Profile* profile)
+PrerenderManager::PrerenderManager(Profile* profile,
+ PrerenderTracker* prerender_tracker)
: rate_limit_enabled_(true),
enabled_(true),
profile_(profile),
+ prerender_tracker_(prerender_tracker),
max_prerender_age_(base::TimeDelta::FromSeconds(
kDefaultMaxPrerenderAgeSeconds)),
max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB),
@@ -454,7 +457,7 @@ bool PrerenderManager::MaybeUsePreloadedPageOld(TabContents* tab_contents,
// Try to set the prerendered page as used, so any subsequent attempts to
// cancel on other threads will fail. If this fails because the prerender
// was already cancelled, possibly on another thread, fail.
- if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
+ if (!prerender_tracker_->TryUse(child_id, route_id))
return false;
if (!prerender_contents->load_start_time().is_null())
@@ -566,7 +569,7 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
// Try to set the prerendered page as used, so any subsequent attempts to
// cancel on other threads will fail. If this fails because the prerender
// was already cancelled, possibly on another thread, fail.
- if (!PrerenderTracker::GetInstance()->TryUse(child_id, route_id))
+ if (!prerender_tracker_->TryUse(child_id, route_id))
return false;
if (!prerender_contents->load_start_time().is_null())
@@ -688,7 +691,7 @@ PrerenderContents* PrerenderManager::CreatePrerenderContents(
const GURL& referrer) {
DCHECK(CalledOnValidThread());
return prerender_contents_factory_->CreatePrerenderContents(
- this, profile_, url, referrer);
+ this, prerender_tracker_, profile_, url, referrer);
}
void PrerenderManager::DeletePendingDeleteEntries() {
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index bbe630c..cd039b6 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -38,6 +38,8 @@ struct hash<TabContents*> {
namespace prerender {
+class PrerenderTracker;
+
// Adds either a preload or a pending preload to the PrerenderManager.
// Must be called on the UI thread.
void HandleTag(
@@ -48,6 +50,12 @@ void HandleTag(
const GURL& referrer,
bool make_pending);
+void DestroyPreloadForRenderView(
+ const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr,
+ int child_id,
+ int route_id,
+ FinalStatus final_status);
+
// PrerenderManager is responsible for initiating and keeping prerendered
// views of webpages. All methods must be called on the UI thread unless
// indicated otherwise.
@@ -65,7 +73,7 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
};
// Owned by a Profile object for the lifetime of the profile.
- explicit PrerenderManager(Profile* profile);
+ PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
virtual ~PrerenderManager();
@@ -268,6 +276,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
Profile* profile_;
+ PrerenderTracker* prerender_tracker_;
+
base::TimeDelta max_prerender_age_;
// Maximum amount of memory, in megabytes, that a single PrerenderContents
// can use before it's cancelled.
diff --git a/chrome/browser/prerender/prerender_manager_unittest.cc b/chrome/browser/prerender/prerender_manager_unittest.cc
index 489aa3c..c1a8973 100644
--- a/chrome/browser/prerender/prerender_manager_unittest.cc
+++ b/chrome/browser/prerender/prerender_manager_unittest.cc
@@ -6,6 +6,7 @@
#include "base/time.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_manager.h"
+#include "chrome/test/testing_browser_process.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_process_host.h"
@@ -19,9 +20,11 @@ namespace {
class DummyPrerenderContents : public PrerenderContents {
public:
DummyPrerenderContents(PrerenderManager* prerender_manager,
+ PrerenderTracker* prerender_tracker,
const GURL& url,
FinalStatus expected_final_status)
- : PrerenderContents(prerender_manager, NULL, url, GURL()),
+ : PrerenderContents(prerender_manager, prerender_tracker, NULL, url,
+ GURL()),
has_started_(false),
expected_final_status_(expected_final_status) {
}
@@ -56,11 +59,12 @@ class DummyPrerenderContents : public PrerenderContents {
class TestPrerenderManager : public PrerenderManager {
public:
- TestPrerenderManager()
- : PrerenderManager(NULL),
+ explicit TestPrerenderManager(PrerenderTracker* prerender_tracker)
+ : PrerenderManager(NULL, prerender_tracker),
time_(base::Time::Now()),
time_ticks_(base::TimeTicks::Now()),
- next_prerender_contents_(NULL) {
+ next_prerender_contents_(NULL),
+ prerender_tracker_(prerender_tracker) {
rate_limit_enabled_ = false;
}
@@ -92,7 +96,8 @@ class TestPrerenderManager : public PrerenderManager {
const GURL& url,
FinalStatus expected_final_status) {
DummyPrerenderContents* prerender_contents =
- new DummyPrerenderContents(this, url, expected_final_status);
+ new DummyPrerenderContents(this, prerender_tracker_, url,
+ expected_final_status);
SetNextPrerenderContents(prerender_contents);
return prerender_contents;
}
@@ -102,7 +107,8 @@ class TestPrerenderManager : public PrerenderManager {
const std::vector<GURL>& alias_urls,
FinalStatus expected_final_status) {
DummyPrerenderContents* prerender_contents =
- new DummyPrerenderContents(this, url, expected_final_status);
+ new DummyPrerenderContents(this, prerender_tracker_, url,
+ expected_final_status);
for (std::vector<GURL>::const_iterator it = alias_urls.begin();
it != alias_urls.end();
++it) {
@@ -156,6 +162,8 @@ class TestPrerenderManager : public PrerenderManager {
// PrerenderContents with an |expected_final_status| of FINAL_STATUS_USED,
// tracked so they will be automatically deleted.
ScopedVector<PrerenderContents> used_prerender_contents_;
+
+ PrerenderTracker* prerender_tracker_;
};
class RestorePrerenderMode {
@@ -173,7 +181,8 @@ class RestorePrerenderMode {
class PrerenderManagerTest : public testing::Test {
public:
PrerenderManagerTest() : ui_thread_(BrowserThread::UI, &message_loop_),
- prerender_manager_(new TestPrerenderManager()) {
+ prerender_manager_(
+ new TestPrerenderManager(prerender_tracker())) {
}
TestPrerenderManager* prerender_manager() {
@@ -181,7 +190,12 @@ class PrerenderManagerTest : public testing::Test {
}
private:
+ PrerenderTracker* prerender_tracker() {
+ return browser_process_.get()->prerender_tracker();
+ }
+
// Needed to pass PrerenderManager's DCHECKs.
+ ScopedTestingBrowserProcess browser_process_;
MessageLoop message_loop_;
BrowserThread ui_thread_;
scoped_ptr<TestPrerenderManager> prerender_manager_;
diff --git a/chrome/browser/prerender/prerender_tracker.cc b/chrome/browser/prerender/prerender_tracker.cc
index f191e8c..19de266 100644
--- a/chrome/browser/prerender/prerender_tracker.cc
+++ b/chrome/browser/prerender/prerender_tracker.cc
@@ -2,45 +2,33 @@
// 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_tracker.h"
+
#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/prerender/prerender_manager.h"
-#include "chrome/browser/prerender/prerender_tracker.h"
#include "content/browser/browser_thread.h"
+#include "content/browser/resource_context.h"
+#include "content/common/resource_messages.h"
+#include "net/base/load_flags.h"
namespace prerender {
-namespace {
-
-void DestroyPreloadForRenderView(
- const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr,
- int child_id,
- int route_id,
- FinalStatus final_status) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get();
- if (!prerender_manager)
- return;
-
- prerender_manager->DestroyPreloadForChildRouteIdPair(
- std::make_pair(child_id, route_id),
- final_status);
-}
-
-} // namespace
-
struct RenderViewInfo {
explicit RenderViewInfo(PrerenderManager* prerender_manager)
: final_status(FINAL_STATUS_MAX),
prerender_manager(prerender_manager->AsWeakPtr()) {
}
+ ~RenderViewInfo() {}
FinalStatus final_status;
base::WeakPtr<PrerenderManager> prerender_manager;
};
-// static
-PrerenderTracker* PrerenderTracker::GetInstance() {
- return Singleton<PrerenderTracker>::get();
+PrerenderTracker::PrerenderTracker() {
+}
+
+PrerenderTracker::~PrerenderTracker() {
}
bool PrerenderTracker::TryUse(int child_id, int route_id) {
@@ -74,15 +62,6 @@ bool PrerenderTracker::TryCancelOnIOThread(
return TryCancel(child_id, route_id, final_status);
}
-bool PrerenderTracker::IsPrerenderingOnIOThread(int child_id,
- int route_id) const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- ChildRouteIdPair child_route_id_pair(child_id, route_id);
- return possibly_prerendering_io_thread_set_.end() !=
- possibly_prerendering_io_thread_set_.find(child_route_id_pair);
-}
-
bool PrerenderTracker::GetFinalStatus(int child_id, int route_id,
FinalStatus* final_status) const {
ChildRouteIdPair child_route_id_pair(child_id, route_id);
@@ -118,12 +97,6 @@ void PrerenderTracker::OnPrerenderingStarted(
std::make_pair(child_route_id_pair, RenderViewInfo(prerender_manager)));
}
-PrerenderTracker::PrerenderTracker() {
-}
-
-PrerenderTracker::~PrerenderTracker() {
-}
-
void PrerenderTracker::OnPrerenderingFinished(int child_id, int route_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK_GE(child_id, 0);
@@ -180,6 +153,15 @@ bool PrerenderTracker::SetFinalStatus(int child_id, int route_id,
return false;
}
+bool PrerenderTracker::IsPrerenderingOnIOThread(int child_id,
+ int route_id) const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ ChildRouteIdPair child_route_id_pair(child_id, route_id);
+ return possibly_prerendering_io_thread_set_.end() !=
+ possibly_prerendering_io_thread_set_.find(child_route_id_pair);
+}
+
void PrerenderTracker::AddPrerenderOnIOThread(
const ChildRouteIdPair& child_route_id_pair) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -201,13 +183,15 @@ void PrerenderTracker::RemovePrerenderOnIOThread(
// static
void PrerenderTracker::AddPrerenderOnIOThreadTask(
const ChildRouteIdPair& child_route_id_pair) {
- GetInstance()->AddPrerenderOnIOThread(child_route_id_pair);
+ g_browser_process->prerender_tracker()->AddPrerenderOnIOThread(
+ child_route_id_pair);
}
// static
void PrerenderTracker::RemovePrerenderOnIOThreadTask(
const ChildRouteIdPair& child_route_id_pair) {
- GetInstance()->RemovePrerenderOnIOThread(child_route_id_pair);
+ g_browser_process->prerender_tracker()->RemovePrerenderOnIOThread(
+ child_route_id_pair);
}
} // namespace prerender
diff --git a/chrome/browser/prerender/prerender_tracker.h b/chrome/browser/prerender/prerender_tracker.h
index acd8e8d..3167fa1 100644
--- a/chrome/browser/prerender/prerender_tracker.h
+++ b/chrome/browser/prerender/prerender_tracker.h
@@ -9,7 +9,7 @@
#include <map>
#include <set>
-#include "base/memory/singleton.h"
+#include "base/gtest_prod_util.h"
#include "base/synchronization/lock.h"
#include "chrome/browser/prerender/prerender_final_status.h"
@@ -23,8 +23,8 @@ struct RenderViewInfo;
// and can be modified on any thread.
class PrerenderTracker {
public:
- // Returns the PrerenderTracker singleton.
- static PrerenderTracker* GetInstance();
+ PrerenderTracker();
+ ~PrerenderTracker();
// Attempts to set the status of the specified RenderViewHost to
// FINAL_STATUS_USED. Returns true on success. Returns false if it has
@@ -53,22 +53,21 @@ class PrerenderTracker {
bool TryCancelOnIOThread(int child_id, int route_id,
FinalStatus final_status);
- // Returns whether or not a RenderView is prerendering. Can only be called on
- // the IO thread. Does not acquire a lock, so may claim a RenderView that has
- // been displayed or destroyed is still prerendering.
- // TODO(mmenke): Remove external use of this method and make it private.
- bool IsPrerenderingOnIOThread(int child_id, int route_id) const;
-
// Gets the FinalStatus of the specified prerendered RenderView. Returns
// |true| and sets |final_status| to the status of the RenderView if it
// is found, returns false otherwise.
bool GetFinalStatus(int child_id, int route_id,
FinalStatus* final_status) const;
+ // Returns whether or not a RenderView is prerendering. Can only be called on
+ // the IO thread. Does not acquire a lock, so may claim a RenderView that has
+ // been displayed or destroyed is still prerendering.
+ bool IsPrerenderingOnIOThread(int child_id, int route_id) const;
+
private:
- friend struct DefaultSingletonTraits<PrerenderTracker>;
friend class PrerenderContents;
+ FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerNull);
FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerUsed);
FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelled);
FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelledOnIO);
@@ -82,9 +81,6 @@ class PrerenderTracker {
// Set of child/route id pairs that may be prerendering.
typedef std::set<ChildRouteIdPair> PossiblyPrerenderingChildRouteIdPairs;
- PrerenderTracker();
- ~PrerenderTracker();
-
// Must be called when a RenderView starts prerendering, before the first
// navigation starts to avoid any races.
void OnPrerenderingStarted(int child_id, int route_id,
diff --git a/chrome/browser/prerender/prerender_tracker_unittest.cc b/chrome/browser/prerender/prerender_tracker_unittest.cc
index 4ed6f83..b89ddbd 100644
--- a/chrome/browser/prerender/prerender_tracker_unittest.cc
+++ b/chrome/browser/prerender/prerender_tracker_unittest.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_tracker.h"
+#include "chrome/test/testing_browser_process.h"
#include "content/browser/browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,7 +17,8 @@ namespace {
class TestPrerenderManager : public PrerenderManager {
public:
- TestPrerenderManager() : PrerenderManager(NULL) {
+ explicit TestPrerenderManager(PrerenderTracker* prerender_tracker) :
+ PrerenderManager(NULL, prerender_tracker) {
rate_limit_enabled_ = false;
}
@@ -42,7 +44,7 @@ class PrerenderTrackerTest : public testing::Test {
PrerenderTrackerTest() :
ui_thread_(BrowserThread::UI, &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_),
- prerender_manager_(new TestPrerenderManager()) {
+ prerender_manager_(new TestPrerenderManager(prerender_tracker())) {
}
TestPrerenderManager* prerender_manager() {
@@ -50,7 +52,7 @@ class PrerenderTrackerTest : public testing::Test {
}
PrerenderTracker* prerender_tracker() {
- return PrerenderTracker::GetInstance();
+ return browser_process_.get()->prerender_tracker();
}
int GetCurrentStatus(int child_id, int route_id) {
@@ -68,6 +70,7 @@ class PrerenderTrackerTest : public testing::Test {
}
private:
+ ScopedTestingBrowserProcess browser_process_;
MessageLoop message_loop_;
BrowserThread ui_thread_;
BrowserThread io_thread_;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 75e0694..650901c 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1645,7 +1645,11 @@ PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() {
prerender::PrerenderManager* ProfileImpl::GetPrerenderManager() {
if (!prerender::PrerenderManager::IsPrerenderingPossible())
return NULL;
- if (!prerender_manager_.get())
- prerender_manager_.reset(new prerender::PrerenderManager(this));
+ if (!prerender_manager_.get()) {
+ CHECK(g_browser_process->prerender_tracker());
+ prerender_manager_.reset(
+ new prerender::PrerenderManager(
+ this, g_browser_process->prerender_tracker()));
+ }
return prerender_manager_.get();
}
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc
new file mode 100644
index 0000000..26e03b1
--- /dev/null
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2011 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/renderer_host/chrome_resource_dispatcher_host_observer.h"
+
+#include "base/logging.h"
+#include "chrome/browser/prerender/prerender_manager.h"
+#include "chrome/browser/prerender/prerender_tracker.h"
+#include "content/browser/browser_thread.h"
+#include "content/browser/resource_context.h"
+#include "content/common/resource_messages.h"
+#include "net/base/load_flags.h"
+
+ChromeResourceDispatcherHostObserver::ChromeResourceDispatcherHostObserver(
+ prerender::PrerenderTracker* prerender_tracker)
+ : prerender_tracker_(prerender_tracker) {
+}
+
+ChromeResourceDispatcherHostObserver::~ChromeResourceDispatcherHostObserver() {
+}
+
+bool ChromeResourceDispatcherHostObserver::ShouldBeginRequest(
+ int child_id, int route_id,
+ const ResourceHostMsg_Request& request_data,
+ const content::ResourceContext& resource_context,
+ const GURL& referrer) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ bool is_prerendering = prerender_tracker_->IsPrerenderingOnIOThread(
+ child_id, route_id);
+
+ // Handle a PREFETCH resource type. If prefetch is disabled, squelch the
+ // request. Otherwise, do a normal request to warm the cache.
+ if (request_data.resource_type == ResourceType::PREFETCH) {
+ // All PREFETCH requests should be GETs, but be defensive about it.
+ if (request_data.method != "GET")
+ return false;
+
+ // If prefetch is disabled, kill the request.
+ if (!ResourceDispatcherHost::is_prefetch_enabled())
+ return false;
+ }
+
+ // Handle a PRERENDER motivated request. Very similar to rel=prefetch, these
+ // rel=prerender requests instead launch an early render of the entire page.
+ if (request_data.resource_type == ResourceType::PRERENDER) {
+ if (prerender::PrerenderManager::IsPrerenderingPossible()) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableFunction(prerender::HandleTag,
+ resource_context.prerender_manager(),
+ child_id,
+ route_id,
+ request_data.url,
+ referrer,
+ is_prerendering));
+ }
+ // Prerendering or not, this request should be aborted.
+ return false;
+ }
+
+ // Abort any prerenders that spawn requests that use invalid HTTP methods.
+ if (is_prerendering &&
+ !prerender::PrerenderManager::IsValidHttpMethod(request_data.method)) {
+ prerender_tracker_->TryCancelOnIOThread(
+ child_id, route_id,
+ prerender::FINAL_STATUS_INVALID_HTTP_METHOD);
+ return false;
+ }
+
+ return true;
+}
+
+void ChromeResourceDispatcherHostObserver::MutateLoadFlags(int child_id,
+ int route_id,
+ int* load_flags) {
+ DCHECK(load_flags);
+ if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id))
+ *load_flags |= net::LOAD_PRERENDERING;
+}
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h
new file mode 100644
index 0000000..d544e62
--- /dev/null
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2011 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_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_OBSERVER_H_
+#define CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_OBSERVER_H_
+#pragma once
+
+#include "content/browser/renderer_host/resource_dispatcher_host.h"
+
+namespace prerender {
+class PrerenderTracker;
+}
+
+// Implements ResourceDispatcherHost::Observer. Currently used by the Prerender
+// system to abort requests and add to the load flags when a request begins.
+class ChromeResourceDispatcherHostObserver
+ : public ResourceDispatcherHost::Observer {
+ public:
+ // This class does not take ownership of the tracker but merely holds a
+ // reference to it to avoid accessing g_browser_process. The PrerenderTracker
+ // will be destroyed after the observer.
+ explicit ChromeResourceDispatcherHostObserver(
+ prerender::PrerenderTracker* prerender_tracker);
+ virtual ~ChromeResourceDispatcherHostObserver();
+
+ // ResourceDispatcherHost::Observer implementation.
+ virtual bool ShouldBeginRequest(
+ int child_id, int route_id,
+ const ResourceHostMsg_Request& request_data,
+ const content::ResourceContext& resource_context,
+ const GURL& referrer) OVERRIDE;
+
+ virtual void MutateLoadFlags(int child_id, int route_id,
+ int* load_flags) OVERRIDE;
+
+ private:
+ prerender::PrerenderTracker* prerender_tracker_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeResourceDispatcherHostObserver);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_OBSERVER_H_