diff options
author | dominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 19:03:27 +0000 |
---|---|---|
committer | dominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 19:03:27 +0000 |
commit | 1459fb6d13c6e8da1fd72a569e9410a1d038bd59 (patch) | |
tree | 869478ccf95444e29cffb9e5e70acc0015379057 /chrome/browser | |
parent | 8b001f3e36a29f590e57d46e8e1b357685eb38c1 (diff) | |
download | chromium_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.h | 6 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 14 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 10 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_browsertest.cc | 8 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_contents.cc | 37 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_contents.h | 8 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.cc | 11 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.h | 12 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager_unittest.cc | 28 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_tracker.cc | 64 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_tracker.h | 22 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_tracker_unittest.cc | 9 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_impl.cc | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.cc | 79 | ||||
-rw-r--r-- | chrome/browser/renderer_host/chrome_resource_dispatcher_host_observer.h | 43 |
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_ |