summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit.cc9
-rw-r--r--chrome/browser/autofill/autofill_browsertest.cc1
-rw-r--r--chrome/browser/browser_about_handler.cc10
-rw-r--r--chrome/browser/browser_main.cc99
-rw-r--r--chrome/browser/browser_main.h4
-rw-r--r--chrome/browser/browser_process_impl.cc1
-rw-r--r--chrome/browser/browser_shutdown.cc5
-rw-r--r--chrome/browser/browsing_data_remover.cc9
-rw-r--r--chrome/browser/chrome_content_browser_client.cc8
-rw-r--r--chrome/browser/io_thread.cc99
-rw-r--r--chrome/browser/io_thread.h52
-rw-r--r--chrome/browser/net/connect_interceptor.cc33
-rw-r--r--chrome/browser/net/connect_interceptor.h30
-rw-r--r--chrome/browser/net/net_pref_observer.cc12
-rw-r--r--chrome/browser/net/net_pref_observer.h8
-rw-r--r--chrome/browser/net/predictor.cc926
-rw-r--r--chrome/browser/net/predictor.h246
-rw-r--r--chrome/browser/net/predictor_unittest.cc191
-rw-r--r--chrome/browser/prefs/browser_prefs.cc4
-rw-r--r--chrome/browser/profiles/profile.cc4
-rw-r--r--chrome/browser/profiles/profile.h6
-rw-r--r--chrome/browser/profiles/profile_impl.cc22
-rw-r--r--chrome/browser/profiles/profile_impl.h3
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.cc35
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.h11
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.cc9
-rw-r--r--chrome/browser/renderer_host/chrome_render_view_host_observer.cc13
-rw-r--r--chrome/browser/renderer_host/chrome_render_view_host_observer.h9
-rw-r--r--chrome/browser/ui/browser_init.cc8
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--net/url_request/url_request.h1
31 files changed, 629 insertions, 1241 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc
index 98da003..5cea1c0 100644
--- a/chrome/browser/autocomplete/autocomplete_edit.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit.cc
@@ -22,7 +22,7 @@
#include "chrome/browser/extensions/extension_omnibox_api.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/instant/instant_controller.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
@@ -1083,11 +1083,8 @@ void AutocompleteEditModel::DoPrerender(const AutocompleteMatch& match) {
void AutocompleteEditModel::DoPreconnect(const AutocompleteMatch& match) {
if (!match.destination_url.SchemeIs(chrome::kExtensionScheme)) {
// Warm up DNS Prefetch cache, or preconnect to a search service.
- if (profile_->GetNetworkPredictor()) {
- profile_->GetNetworkPredictor()->AnticipateOmniboxUrl(
- match.destination_url,
- IsPreconnectable(match.type));
- }
+ chrome_browser_net::AnticipateOmniboxUrl(match.destination_url,
+ IsPreconnectable(match.type));
// We could prefetch the alternate nav URL, if any, but because there
// can be many of these as a user types an initial series of characters,
// the OS DNS cache could suffer eviction problems for minimal gain.
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index 59e1d44..7c41ba4 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/autofill/autofill_common_test.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/autofill/personal_data_manager.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/translate/translate_infobar_delegate.h"
#include "chrome/browser/translate/translate_manager.h"
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index 340c604..c4158c2 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -30,7 +30,7 @@
#include "chrome/browser/defaults.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/profiles/profile.h"
@@ -703,20 +703,18 @@ class AboutDnsHandler : public base::RefCountedThreadSafe<AboutDnsHandler> {
// Calls FinishOnUIThread() on completion.
void StartOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chrome_browser_net::Predictor* predictor =
- source_->profile()->GetNetworkPredictor();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(this, &AboutDnsHandler::StartOnIOThread, predictor));
+ NewRunnableMethod(this, &AboutDnsHandler::StartOnIOThread));
}
- void StartOnIOThread(chrome_browser_net::Predictor* predictor) {
+ void StartOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
std::string data;
AppendHeader(&data, 0, "About DNS");
AppendBody(&data);
- chrome_browser_net::Predictor::PredictorGetHtmlInfo(predictor, &data);
+ chrome_browser_net::PredictorGetHtmlInfo(&data);
AppendFooter(&data);
BrowserThread::PostTask(
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index a9063cf..be43c54 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -55,7 +55,7 @@
#include "chrome/browser/net/chrome_dns_cert_provenance_checker.h"
#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h"
#include "chrome/browser/net/chrome_net_log.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/policy/browser_policy_connector.h"
@@ -1172,88 +1172,6 @@ void BrowserMainParts::ConnectBackupJobsFieldTrial() {
}
}
-void BrowserMainParts::PredictorFieldTrial() {
- const base::FieldTrial::Probability kDivisor = 1000;
- // For each option (i.e., non-default), we have a fixed probability.
- // 0.1% probability.
- const base::FieldTrial::Probability kProbabilityPerGroup = 1;
-
- // After June 30, 2011 builds, it will always be in default group
- // (default_enabled_prefetch).
- scoped_refptr<base::FieldTrial> trial(
- new base::FieldTrial("DnsImpact", kDivisor,
- "default_enabled_prefetch", 2011, 10, 30));
-
- // First option is to disable prefetching completely.
- int disabled_prefetch = trial->AppendGroup("disabled_prefetch",
- kProbabilityPerGroup);
-
- // We're running two experiments at the same time. The first set of trials
- // modulates the delay-time until we declare a congestion event (and purge
- // our queue). The second modulates the number of concurrent resolutions
- // we do at any time. Users are in exactly one trial (or the default) during
- // any one run, and hence only one experiment at a time.
- // Experiment 1:
- // Set congestion detection at 250, 500, or 750ms, rather than the 1 second
- // default.
- int max_250ms_prefetch = trial->AppendGroup("max_250ms_queue_prefetch",
- kProbabilityPerGroup);
- int max_500ms_prefetch = trial->AppendGroup("max_500ms_queue_prefetch",
- kProbabilityPerGroup);
- int max_750ms_prefetch = trial->AppendGroup("max_750ms_queue_prefetch",
- kProbabilityPerGroup);
- // Set congestion detection at 2 seconds instead of the 1 second default.
- int max_2s_prefetch = trial->AppendGroup("max_2s_queue_prefetch",
- kProbabilityPerGroup);
- // Experiment 2:
- // Set max simultaneous resoultions to 2, 4, or 6, and scale the congestion
- // limit proportionally (so we don't impact average probability of asserting
- // congesion very much).
- int max_2_concurrent_prefetch = trial->AppendGroup(
- "max_2 concurrent_prefetch", kProbabilityPerGroup);
- int max_4_concurrent_prefetch = trial->AppendGroup(
- "max_4 concurrent_prefetch", kProbabilityPerGroup);
- int max_6_concurrent_prefetch = trial->AppendGroup(
- "max_6 concurrent_prefetch", kProbabilityPerGroup);
-
- if (trial->group() != disabled_prefetch) {
- // Initialize the DNS prefetch system.
- size_t max_parallel_resolves =
- chrome_browser_net::Predictor::kMaxSpeculativeParallelResolves;
- int max_queueing_delay_ms =
- chrome_browser_net::Predictor::kMaxSpeculativeResolveQueueDelayMs;
-
- if (trial->group() == max_2_concurrent_prefetch)
- max_parallel_resolves = 2;
- else if (trial->group() == max_4_concurrent_prefetch)
- max_parallel_resolves = 4;
- else if (trial->group() == max_6_concurrent_prefetch)
- max_parallel_resolves = 6;
- chrome_browser_net::Predictor::set_max_parallel_resolves(
- max_parallel_resolves);
-
- if (trial->group() == max_250ms_prefetch) {
- max_queueing_delay_ms =
- (250 * chrome_browser_net::Predictor::kTypicalSpeculativeGroupSize) /
- max_parallel_resolves;
- } else if (trial->group() == max_500ms_prefetch) {
- max_queueing_delay_ms =
- (500 * chrome_browser_net::Predictor::kTypicalSpeculativeGroupSize) /
- max_parallel_resolves;
- } else if (trial->group() == max_750ms_prefetch) {
- max_queueing_delay_ms =
- (750 * chrome_browser_net::Predictor::kTypicalSpeculativeGroupSize) /
- max_parallel_resolves;
- } else if (trial->group() == max_2s_prefetch) {
- max_queueing_delay_ms =
- (2000 * chrome_browser_net::Predictor::kTypicalSpeculativeGroupSize) /
- max_parallel_resolves;
- }
- chrome_browser_net::Predictor::set_max_queueing_delay(
- max_queueing_delay_ms);
- }
-}
-
// Test the impact on subsequent Google searches of getting suggestions from
// www.google.TLD instead of clients1.google.TLD.
void BrowserMainParts::SuggestPrefixFieldTrial() {
@@ -1354,7 +1272,6 @@ void BrowserMainParts::SetupFieldTrials(bool metrics_recording_enabled,
ConnectBackupJobsFieldTrial();
SuggestPrefixFieldTrial();
WarmConnectionFieldTrial();
- PredictorFieldTrial();
}
// -----------------------------------------------------------------------------
@@ -1927,6 +1844,20 @@ int BrowserMain(const MainFunctionParams& parameters) {
RegisterApplicationRestart(parsed_command_line);
#endif // OS_WIN
+ // Initialize and maintain network predictor module, which handles DNS
+ // pre-resolution, as well as TCP/IP connection pre-warming.
+ // This also registers an observer to discard data when closing incognito
+ // mode.
+ bool preconnect_enabled = true; // Default status (easy to change!).
+ if (parsed_command_line.HasSwitch(switches::kDisablePreconnect))
+ preconnect_enabled = false;
+ else if (parsed_command_line.HasSwitch(switches::kEnablePreconnect))
+ preconnect_enabled = true;
+ chrome_browser_net::PredictorInit dns_prefetch(
+ user_prefs,
+ local_state,
+ preconnect_enabled);
+
#if defined(OS_WIN)
base::win::ScopedCOMInitializer com_initializer;
diff --git a/chrome/browser/browser_main.h b/chrome/browser/browser_main.h
index b6ee4f2..e4c1da21 100644
--- a/chrome/browser/browser_main.h
+++ b/chrome/browser/browser_main.h
@@ -142,10 +142,6 @@ class BrowserMainParts {
// A/B test for using a different host prefix in Google search suggest.
void SuggestPrefixFieldTrial();
- // Field trial to see what disabling DNS pre-resolution does to
- // latency of page loads.
- void PredictorFieldTrial();
-
// Used to initialize NSPR where appropriate.
virtual void InitializeSSL() = 0;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 39bf561..0a8a385 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -36,6 +36,7 @@
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/browser/net/chrome_net_log.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/policy/browser_policy_connector.h"
diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc
index c18d22f..92683fe 100644
--- a/chrome/browser/browser_shutdown.cc
+++ b/chrome/browser/browser_shutdown.cc
@@ -38,6 +38,7 @@
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host.h"
+#include "net/predictor_api.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_WIN)
@@ -139,6 +140,10 @@ void Shutdown() {
// time to get here. If you have something that *must* happen on end session,
// consider putting it in BrowserProcessImpl::EndSession.
PrefService* prefs = g_browser_process->local_state();
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ PrefService* user_prefs = profile_manager->GetDefaultProfile()->GetPrefs();
+
+ chrome_browser_net::SavePredictorStateForNextStartupAndTrim(user_prefs);
MetricsService* metrics = g_browser_process->metrics_service();
if (metrics)
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index 138ce0c..56bbd7d 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/net/chrome_url_request_context.h"
-#include "chrome/browser/net/predictor.h"
#include "chrome/browser/password_manager/password_store.h"
#include "chrome/browser/plugin_data_remover.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -366,13 +365,7 @@ void BrowsingDataRemover::ClearNetworkingHistory(IOThread* io_thread) {
// This function should be called on the IO thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- io_thread->ClearHostCache();
-
- chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
- if (predictor) {
- predictor->DiscardInitialNavigationHistory();
- predictor->DiscardAllResults();
- }
+ io_thread->ClearNetworkingHistory();
// Notify the UI thread that we are done.
BrowserThread::PostTask(
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 10fa779..f6f3f13 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -102,13 +102,7 @@ namespace chrome {
void ChromeContentBrowserClient::RenderViewHostCreated(
RenderViewHost* render_view_host) {
-
- SiteInstance* site_instance = render_view_host->site_instance();
- Profile* profile = Profile::FromBrowserContext(
- site_instance->browsing_instance()->browser_context());
-
- new ChromeRenderViewHostObserver(render_view_host,
- profile->GetNetworkPredictor());
+ new ChromeRenderViewHostObserver(render_view_host);
new DevToolsHandler(render_view_host);
new ExtensionMessageHandler(render_view_host);
}
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 7bea24f..b8f3557 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -24,6 +24,7 @@
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/connect_interceptor.h"
#include "chrome/browser/net/passive_log_collector.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/pref_proxy_config_service.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/browser/prefs/pref_service.h"
@@ -343,6 +344,8 @@ IOThread::IOThread(
net_log_(net_log),
extension_event_router_forwarder_(extension_event_router_forwarder),
globals_(NULL),
+ speculative_interceptor_(NULL),
+ predictor_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
// We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
// sure that everything is initialized in the right order.
@@ -384,6 +387,33 @@ ChromeNetLog* IOThread::net_log() {
return net_log_;
}
+void IOThread::InitNetworkPredictor(
+ bool prefetching_enabled,
+ base::TimeDelta max_dns_queue_delay,
+ size_t max_speculative_parallel_resolves,
+ const chrome_common_net::UrlList& startup_urls,
+ ListValue* referral_list,
+ bool preconnect_enabled) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ message_loop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &IOThread::InitNetworkPredictorOnIOThread,
+ prefetching_enabled, max_dns_queue_delay,
+ max_speculative_parallel_resolves,
+ startup_urls, referral_list, preconnect_enabled));
+}
+
+void IOThread::ChangedToOnTheRecord() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ message_loop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &IOThread::ChangedToOnTheRecordOnIOThread));
+}
+
net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!system_url_request_context_getter_) {
@@ -392,6 +422,15 @@ net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
return system_url_request_context_getter_;
}
+void IOThread::ClearNetworkingHistory() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ClearHostCache();
+ // Discard acrued data used to speculate in the future.
+ chrome_browser_net::DiscardInitialNavigationHistory();
+ if (predictor_)
+ predictor_->DiscardAllResults();
+}
+
void IOThread::Init() {
// Though this thread is called the "IO" thread, it actually just routes
// messages around; it shouldn't be allowed to perform any blocking disk I/O.
@@ -488,6 +527,21 @@ void IOThread::CleanUp() {
// This must be reset before the ChromeNetLog is destroyed.
network_change_observer_.reset();
+ // Not initialized in Init(). May not be initialized.
+ if (predictor_) {
+ predictor_->Shutdown();
+
+ // TODO(willchan): Stop reference counting Predictor. It's owned by
+ // IOThread now.
+ predictor_->Release();
+ predictor_ = NULL;
+ chrome_browser_net::FreePredictorResources();
+ }
+
+ // Deletion will unregister this interceptor.
+ delete speculative_interceptor_;
+ speculative_interceptor_ = NULL;
+
system_proxy_config_service_.reset();
delete globals_;
@@ -544,6 +598,51 @@ net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
negotiate_enable_port_);
}
+void IOThread::InitNetworkPredictorOnIOThread(
+ bool prefetching_enabled,
+ base::TimeDelta max_dns_queue_delay,
+ size_t max_speculative_parallel_resolves,
+ const chrome_common_net::UrlList& startup_urls,
+ ListValue* referral_list,
+ bool preconnect_enabled) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ CHECK(!predictor_);
+
+ chrome_browser_net::EnablePredictor(prefetching_enabled);
+
+ predictor_ = new chrome_browser_net::Predictor(
+ globals_->host_resolver.get(),
+ max_dns_queue_delay,
+ max_speculative_parallel_resolves,
+ preconnect_enabled);
+ predictor_->AddRef();
+
+ // Speculative_interceptor_ is used to predict subresource usage.
+ DCHECK(!speculative_interceptor_);
+ speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor;
+
+ FinalizePredictorInitialization(predictor_, startup_urls, referral_list);
+}
+
+void IOThread::ChangedToOnTheRecordOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (predictor_) {
+ // Destroy all evidence of our OTR session.
+ // Note: OTR mode never saves InitialNavigationHistory data.
+ predictor_->Predictor::DiscardAllResults();
+ }
+
+ // Clear the host cache to avoid showing entries from the OTR session
+ // in about:net-internals.
+ ClearHostCache();
+
+ // Clear all of the passively logged data.
+ // TODO(eroman): this is a bit heavy handed, really all we need to do is
+ // clear the data pertaining to incognito context.
+ net_log_->ClearAllPassivelyCapturedEvents();
+}
+
void IOThread::ClearHostCache() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 9340f39..a2b42b5 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -14,6 +14,7 @@
#include "chrome/browser/browser_process_sub_thread.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/prefs/pref_member.h"
+#include "chrome/common/net/predictor_common.h"
#include "net/base/network_change_notifier.h"
class ChromeNetLog;
@@ -28,6 +29,11 @@ namespace base {
class ListValue;
}
+namespace chrome_browser_net {
+class ConnectInterceptor;
+class Predictor;
+} // namespace chrome_browser_net
+
namespace net {
class CertVerifier;
class CookieStore;
@@ -103,13 +109,28 @@ class IOThread : public BrowserProcessSubThread {
ChromeNetLog* net_log();
+ // Initializes the network predictor, which induces DNS pre-resolution and/or
+ // TCP/IP preconnections. |prefetching_enabled| indicates whether or not DNS
+ // prefetching should be enabled, and |preconnect_enabled| controls whether
+ // TCP/IP preconnection is enabled. This should be called by the UI thread.
+ // It will post a task to the IO thread to perform the actual initialization.
+ void InitNetworkPredictor(bool prefetching_enabled,
+ base::TimeDelta max_dns_queue_delay,
+ size_t max_speculative_parallel_resolves,
+ const chrome_common_net::UrlList& startup_urls,
+ base::ListValue* referral_list,
+ bool preconnect_enabled);
+
+ // Handles changing to On The Record mode, discarding confidential data.
+ void ChangedToOnTheRecord();
+
// Returns a getter for the URLRequestContext. Only called on the UI thread.
net::URLRequestContextGetter* system_url_request_context_getter();
- // Clears the host cache. Intended to be used to prevent exposing recently
- // visited sites on about:net-internals/#dns and about:dns pages. Must be
- // called on the IO thread.
- void ClearHostCache();
+ // Clear all network stack history, including the host cache, as well as
+ // speculative data about subresources of visited sites, and startup-time
+ // navigations.
+ void ClearNetworkingHistory();
protected:
virtual void Init();
@@ -131,6 +152,21 @@ class IOThread : public BrowserProcessSubThread {
// SystemURLRequestContextGetter. To be called on IO thread.
void InitSystemRequestContextOnIOThread();
+ void InitNetworkPredictorOnIOThread(
+ bool prefetching_enabled,
+ base::TimeDelta max_dns_queue_delay,
+ size_t max_speculative_parallel_resolves,
+ const chrome_common_net::UrlList& startup_urls,
+ base::ListValue* referral_list,
+ bool preconnect_enabled);
+
+ void ChangedToOnTheRecordOnIOThread();
+
+ // Clears the host cache. Intended to be used to prevent exposing recently
+ // visited sites on about:net-internals/#dns and about:dns pages. Must be
+ // called on the IO thread.
+ void ClearHostCache();
+
// Returns an SSLConfigService instance.
net::SSLConfigService* GetSSLConfigService();
@@ -172,6 +208,14 @@ class IOThread : public BrowserProcessSubThread {
// These member variables are initialized by a task posted to the IO thread,
// which gets posted by calling certain member functions of IOThread.
+
+ // Note: we user explicit pointers rather than smart pointers to be more
+ // explicit about destruction order, and ensure that there is no chance that
+ // these observers would be used accidentally after we have begun to tear
+ // down.
+ chrome_browser_net::ConnectInterceptor* speculative_interceptor_;
+ chrome_browser_net::Predictor* predictor_;
+
scoped_ptr<net::ProxyConfigService> system_proxy_config_service_;
scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
diff --git a/chrome/browser/net/connect_interceptor.cc b/chrome/browser/net/connect_interceptor.cc
index 0ea6dbd..5938df2 100644
--- a/chrome/browser/net/connect_interceptor.cc
+++ b/chrome/browser/net/connect_interceptor.cc
@@ -4,9 +4,8 @@
#include "chrome/browser/net/connect_interceptor.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "net/base/load_flags.h"
-#include "net/url_request/url_request.h"
namespace chrome_browser_net {
@@ -17,24 +16,24 @@ namespace chrome_browser_net {
// TODO(jar): We should do a persistent field trial to validate/optimize this.
static const int kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10;
-ConnectInterceptor::ConnectInterceptor(Predictor* predictor)
+ConnectInterceptor::ConnectInterceptor()
: timed_cache_(base::TimeDelta::FromSeconds(
- kMaxUnusedSocketLifetimeSecondsWithoutAGet)),
- predictor_(predictor) {
- DCHECK(predictor);
+ kMaxUnusedSocketLifetimeSecondsWithoutAGet)) {
+ net::URLRequest::Deprecated::RegisterRequestInterceptor(this);
}
ConnectInterceptor::~ConnectInterceptor() {
+ net::URLRequest::Deprecated::UnregisterRequestInterceptor(this);
}
net::URLRequestJob* ConnectInterceptor::MaybeIntercept(
- net::URLRequest* request) const {
+ net::URLRequest* request) {
GURL request_scheme_host(Predictor::CanonicalizeUrl(request->url()));
if (request_scheme_host == GURL::EmptyGURL())
return NULL;
// Learn what URLs are likely to be needed during next startup.
- predictor_->LearnAboutInitialNavigation(request_scheme_host);
+ LearnAboutInitialNavigation(request_scheme_host);
bool redirected_host = false;
if (request->referrer().empty()) {
@@ -56,8 +55,7 @@ net::URLRequestJob* ConnectInterceptor::MaybeIntercept(
if (request->original_url().path().length() <= 1 &&
timed_cache_.WasRecentlySeen(original_scheme_host)) {
// TODO(jar): These definite redirects could be learned much faster.
- predictor_->LearnFromNavigation(original_scheme_host,
- request_scheme_host);
+ LearnFromNavigation(original_scheme_host, request_scheme_host);
}
}
}
@@ -66,8 +64,7 @@ net::URLRequestJob* ConnectInterceptor::MaybeIntercept(
bool is_subresource = !(request->load_flags() & net::LOAD_MAIN_FRAME);
// Learn about our referring URL, for use in the future.
if (is_subresource && timed_cache_.WasRecentlySeen(referring_scheme_host))
- predictor_->LearnFromNavigation(referring_scheme_host,
- request_scheme_host);
+ LearnFromNavigation(referring_scheme_host, request_scheme_host);
if (referring_scheme_host == request_scheme_host) {
// We've already made any/all predictions when we navigated to the
// referring host, so we can bail out here.
@@ -83,18 +80,18 @@ net::URLRequestJob* ConnectInterceptor::MaybeIntercept(
// main frame request - way back in RenderViewHost::Navigate. So only handle
// predictions now for subresources or for redirected hosts.
if ((request->load_flags() & net::LOAD_SUB_FRAME) || redirected_host)
- predictor_->PredictFrameSubresources(request_scheme_host);
+ PredictFrameSubresources(request_scheme_host);
return NULL;
}
net::URLRequestJob* ConnectInterceptor::MaybeInterceptResponse(
- net::URLRequest* request) const {
+ net::URLRequest* request) {
return NULL;
}
net::URLRequestJob* ConnectInterceptor::MaybeInterceptRedirect(
- const GURL& location,
- net::URLRequest* request) const {
+ net::URLRequest* request,
+ const GURL& location) {
return NULL;
}
@@ -106,7 +103,7 @@ ConnectInterceptor::TimedCache::TimedCache(const base::TimeDelta& max_duration)
// Make Clang compilation happy with explicit destructor.
ConnectInterceptor::TimedCache::~TimedCache() {}
-bool ConnectInterceptor::TimedCache::WasRecentlySeen(const GURL& url) const {
+bool ConnectInterceptor::TimedCache::WasRecentlySeen(const GURL& url) {
DCHECK_EQ(url.GetWithEmptyPath(), url);
// Evict any overly old entries.
base::TimeTicks now = base::TimeTicks::Now();
@@ -120,7 +117,7 @@ bool ConnectInterceptor::TimedCache::WasRecentlySeen(const GURL& url) const {
return mru_cache_.end() != mru_cache_.Peek(url);
}
-void ConnectInterceptor::TimedCache::SetRecentlySeen(const GURL& url) const {
+void ConnectInterceptor::TimedCache::SetRecentlySeen(const GURL& url) {
DCHECK_EQ(url.GetWithEmptyPath(), url);
mru_cache_.Put(url, base::TimeTicks::Now());
}
diff --git a/chrome/browser/net/connect_interceptor.h b/chrome/browser/net/connect_interceptor.h
index 657700e..eca1c17 100644
--- a/chrome/browser/net/connect_interceptor.h
+++ b/chrome/browser/net/connect_interceptor.h
@@ -6,34 +6,30 @@
#define CHROME_BROWSER_NET_CONNECT_INTERCEPTOR_H_
#pragma once
+#include "net/url_request/url_request.h"
+
#include "base/gtest_prod_util.h"
#include "base/memory/mru_cache.h"
-#include "base/time.h"
-#include "net/url_request/url_request_job_factory.h"
namespace chrome_browser_net {
-class Predictor;
-
//------------------------------------------------------------------------------
// An interceptor to monitor URLRequests so that we can do speculative DNS
// resolution and/or speculative TCP preconnections.
-class ConnectInterceptor : public net::URLRequestJobFactory::Interceptor {
+class ConnectInterceptor : public net::URLRequest::Interceptor {
public:
// Construction includes registration as an URL.
- explicit ConnectInterceptor(Predictor* predictor);
+ ConnectInterceptor();
// Destruction includes unregistering.
virtual ~ConnectInterceptor();
protected:
// Overridden from net::URLRequest::Interceptor:
// Learn about referrers, and optionally preconnect based on history.
- virtual net::URLRequestJob* MaybeIntercept(
- net::URLRequest* request) const OVERRIDE;
- virtual net::URLRequestJob* MaybeInterceptResponse(
- net::URLRequest* request) const OVERRIDE;
- virtual net::URLRequestJob* MaybeInterceptRedirect(
- const GURL& location, net::URLRequest* request) const OVERRIDE;
+ virtual net::URLRequestJob* MaybeIntercept(net::URLRequest* request);
+ virtual net::URLRequestJob* MaybeInterceptResponse(net::URLRequest* request);
+ virtual net::URLRequestJob* MaybeInterceptRedirect(net::URLRequest* request,
+ const GURL& location);
private:
// Provide access to local class TimedCache for testing.
@@ -52,20 +48,17 @@ class ConnectInterceptor : public net::URLRequestJobFactory::Interceptor {
// Evicts any entries that have been in the FIFO "too long," and then checks
// to see if the given url is (still) in the FIFO cache.
- bool WasRecentlySeen(const GURL& url) const;
+ bool WasRecentlySeen(const GURL& url);
// Adds the given url to the cache, where it will remain for max_duration_.
- void SetRecentlySeen(const GURL& url) const;
+ void SetRecentlySeen(const GURL& url);
private:
// Our cache will be keyed on a URL (actually, just a scheme/host/port).
// We will always track the time it was last added to the FIFO cache by
// remembering a TimeTicks value.
typedef base::MRUCache<GURL, base::TimeTicks> UrlMruTimedCache;
- // mru_cache_ has to be mutable in order to be accessed from the overriden
- // URLRequestJob functions. It is mutable because it tracks the urls and
- // caches them.
- mutable UrlMruTimedCache mru_cache_;
+ UrlMruTimedCache mru_cache_;
// The longest time an entry can persist in the cache, and still be found.
const base::TimeDelta max_duration_;
@@ -73,7 +66,6 @@ class ConnectInterceptor : public net::URLRequestJobFactory::Interceptor {
DISALLOW_COPY_AND_ASSIGN(TimedCache);
};
TimedCache timed_cache_;
- Predictor* const predictor_;
DISALLOW_COPY_AND_ASSIGN(ConnectInterceptor);
};
diff --git a/chrome/browser/net/net_pref_observer.cc b/chrome/browser/net/net_pref_observer.cc
index 5655f54..abfcc46 100644
--- a/chrome/browser/net/net_pref_observer.cc
+++ b/chrome/browser/net/net_pref_observer.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/net/net_pref_observer.h"
#include "base/task.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
@@ -29,14 +29,10 @@ void SetEnforceThrottlingOnThrottlerManager(bool enforce) {
}
NetPrefObserver::NetPrefObserver(PrefService* prefs,
- prerender::PrerenderManager* prerender_manager,
- chrome_browser_net::Predictor* predictor)
- : prerender_manager_(prerender_manager),
- predictor_(predictor) {
+ prerender::PrerenderManager* prerender_manager)
+ : prerender_manager_(prerender_manager) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(prefs);
- DCHECK(predictor);
-
network_prediction_enabled_.Init(prefs::kNetworkPredictionEnabled, prefs,
this);
spdy_disabled_.Init(prefs::kDisableSpdy, prefs, this);
@@ -61,7 +57,7 @@ void NetPrefObserver::Observe(int type,
void NetPrefObserver::ApplySettings(const std::string* pref_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- predictor_->EnablePredictor(*network_prediction_enabled_);
+ chrome_browser_net::EnablePredictor(*network_prediction_enabled_);
if (prerender_manager_)
prerender_manager_->set_enabled(*network_prediction_enabled_);
net::HttpStreamFactory::set_spdy_enabled(!*spdy_disabled_);
diff --git a/chrome/browser/net/net_pref_observer.h b/chrome/browser/net/net_pref_observer.h
index 4d2ca47..b7b60c0 100644
--- a/chrome/browser/net/net_pref_observer.h
+++ b/chrome/browser/net/net_pref_observer.h
@@ -14,10 +14,6 @@
class Profile;
-namespace chrome_browser_net {
-class Predictor;
-}
-
namespace prerender {
class PrerenderManager;
}
@@ -31,8 +27,7 @@ class NetPrefObserver : public NotificationObserver {
// |prerender_manager| may be NULL. If not, |*prerender_manager| must
// outlive this.
NetPrefObserver(PrefService* prefs,
- prerender::PrerenderManager* prerender_manager,
- chrome_browser_net::Predictor* predictor);
+ prerender::PrerenderManager* prerender_manager);
virtual ~NetPrefObserver();
// NotificationObserver
@@ -50,7 +45,6 @@ class NetPrefObserver : public NotificationObserver {
BooleanPrefMember spdy_disabled_;
BooleanPrefMember http_throttling_enabled_;
prerender::PrerenderManager* prerender_manager_;
- chrome_browser_net::Predictor* predictor_;
DISALLOW_COPY_AND_ASSIGN(NetPrefObserver);
};
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index 358c162..ffc5e57 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -9,23 +9,12 @@
#include <set>
#include <sstream>
-#include "base/bind.h"
-#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/metrics/histogram.h"
-#include "base/stl_util.h"
#include "base/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
#include "base/time.h"
#include "base/values.h"
-#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/preconnect.h"
-#include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/browser/prefs/session_startup_pref.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
@@ -64,25 +53,6 @@ const TimeDelta Predictor::kDurationBetweenTrimmingIncrements =
TimeDelta::FromSeconds(15);
// static
const size_t Predictor::kUrlsTrimmedPerIncrement = 5u;
-// static
-const size_t Predictor::kMaxSpeculativeParallelResolves = 3;
-// To control our congestion avoidance system, which discards a queue when
-// resolutions are "taking too long," we need an expected resolution time.
-// Common average is in the range of 300-500ms.
-const int kExpectedResolutionTimeMs = 500;
-// static
-const int Predictor::kTypicalSpeculativeGroupSize = 8;
-// static
-const int Predictor::kMaxSpeculativeResolveQueueDelayMs =
- (kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) /
- Predictor::kMaxSpeculativeParallelResolves;
-
-static int g_max_queueing_delay_ms = 0;
-static size_t g_max_parallel_resolves = 0u;
-
-// A version number for prefs that are saved. This should be incremented when
-// we change the format so that we discard old data.
-static const int kPredictorStartupFormatVersion = 1;
class Predictor::LookupRequest {
public:
@@ -129,88 +99,76 @@ class Predictor::LookupRequest {
DISALLOW_COPY_AND_ASSIGN(LookupRequest);
};
-Predictor::Predictor(bool preconnect_enabled)
- : initial_observer_(NULL),
- predictor_enabled_(true),
- peak_pending_lookups_(0),
+Predictor::Predictor(net::HostResolver* host_resolver,
+ TimeDelta max_dns_queue_delay,
+ size_t max_concurrent,
+ bool preconnect_enabled)
+ : peak_pending_lookups_(0),
shutdown_(false),
- max_concurrent_dns_lookups_(g_max_parallel_resolves),
- max_dns_queue_delay_(
- TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)),
- host_resolver_(NULL),
+ max_concurrent_dns_lookups_(max_concurrent),
+ max_dns_queue_delay_(max_dns_queue_delay),
+ host_resolver_(host_resolver),
preconnect_enabled_(preconnect_enabled),
consecutive_omnibox_preconnect_count_(0),
- next_trim_time_(base::TimeTicks::Now() + kDurationBetweenTrimmings) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ next_trim_time_(base::TimeTicks::Now() + kDurationBetweenTrimmings),
+ ALLOW_THIS_IN_INITIALIZER_LIST(trim_task_factory_(this)) {
}
Predictor::~Predictor() {
- // TODO(rlp): Add DCHECK for CurrentlyOn(BrowserThread::IO) when the
- // ProfileManagerTest has been updated with a mock profile.
DCHECK(shutdown_);
}
-// static
-Predictor* Predictor::CreatePredictor(
- bool preconnect_enabled, bool simple_shutdown) {
- if (simple_shutdown)
- return new SimpleShutdownPredictor(preconnect_enabled);
- return new Predictor(preconnect_enabled);
-}
+void Predictor::Shutdown() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!shutdown_);
+ shutdown_ = true;
-void Predictor::RegisterUserPrefs(PrefService* user_prefs) {
- user_prefs->RegisterListPref(prefs::kDnsPrefetchingStartupList,
- PrefService::UNSYNCABLE_PREF);
- user_prefs->RegisterListPref(prefs::kDnsPrefetchingHostReferralList,
- PrefService::UNSYNCABLE_PREF);
+ std::set<LookupRequest*>::iterator it;
+ for (it = pending_lookups_.begin(); it != pending_lookups_.end(); ++it)
+ delete *it;
}
-// --------------------- Start UI methods. ------------------------------------
-
-void Predictor::InitNetworkPredictor(PrefService* user_prefs,
- PrefService* local_state,
- IOThread* io_thread) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- predictor_enabled_ = user_prefs->GetBoolean(prefs::kNetworkPredictionEnabled);
-
- // Gather the list of hostnames to prefetch on startup.
- UrlList urls = GetPredictedUrlListAtStartup(user_prefs, local_state);
-
- base::ListValue* referral_list =
- static_cast<base::ListValue*>(user_prefs->GetList(
- prefs::kDnsPrefetchingHostReferralList)->DeepCopy());
-
- // Remove obsolete preferences from local state if necessary.
- int current_version =
- local_state->GetInteger(prefs::kMultipleProfilePrefMigration);
- if ((current_version & browser::DNS_PREFS) == 0) {
- local_state->RegisterListPref(prefs::kDnsStartupPrefetchList,
- PrefService::UNSYNCABLE_PREF);
- local_state->RegisterListPref(prefs::kDnsHostReferralList,
- PrefService::UNSYNCABLE_PREF);
- local_state->ClearPref(prefs::kDnsStartupPrefetchList);
- local_state->ClearPref(prefs::kDnsHostReferralList);
- local_state->SetInteger(prefs::kMultipleProfilePrefMigration,
- current_version | browser::DNS_PREFS);
+// Overloaded Resolve() to take a vector of names.
+void Predictor::ResolveList(const UrlList& urls,
+ UrlInfo::ResolutionMotivation motivation) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ for (UrlList::const_iterator it = urls.begin(); it < urls.end(); ++it) {
+ AppendToResolutionQueue(*it, motivation);
}
+}
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(
- &Predictor::FinalizeInitializationOnIOThread,
- base::Unretained(this),
- urls, referral_list,
- io_thread));
+// Basic Resolve() takes an invidual name, and adds it
+// to the queue.
+void Predictor::Resolve(const GURL& url,
+ UrlInfo::ResolutionMotivation motivation) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!url.has_host())
+ return;
+ AppendToResolutionQueue(url, motivation);
+}
+
+void Predictor::LearnFromNavigation(const GURL& referring_url,
+ const GURL& target_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url));
+ DCHECK_NE(referring_url, GURL::EmptyGURL());
+ DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url));
+ DCHECK_NE(target_url, GURL::EmptyGURL());
+
+ referrers_[referring_url].SuggestHost(target_url);
+ // Possibly do some referrer trimming.
+ TrimReferrers();
}
+enum SubresourceValue {
+ PRECONNECTION,
+ PRERESOLUTION,
+ TOO_NEW,
+ SUBRESOURCE_VALUE_MAX
+};
+
void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!predictor_enabled_)
- return;
- if (!url.is_valid() || !url.has_host())
- return;
std::string host = url.HostNoBrackets();
bool is_new_host_request = (host != last_omnibox_host_);
last_omnibox_host_ = host;
@@ -274,16 +232,11 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&Predictor::Resolve, base::Unretained(this),
- CanonicalizeUrl(url), motivation));
+ NewRunnableMethod(this, &Predictor::Resolve, CanonicalizeUrl(url),
+ motivation));
}
void Predictor::PreconnectUrlAndSubresources(const GURL& url) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!predictor_enabled_)
- return;
- if (!url.is_valid() || !url.has_host())
- return;
if (preconnect_enabled()) {
std::string host = url.HostNoBrackets();
UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED);
@@ -294,186 +247,63 @@ void Predictor::PreconnectUrlAndSubresources(const GURL& url) {
}
}
-UrlList Predictor::GetPredictedUrlListAtStartup(
- PrefService* user_prefs,
- PrefService* local_state) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- UrlList urls;
- // Recall list of URLs we learned about during last session.
- // This may catch secondary hostnames, pulled in by the homepages. It will
- // also catch more of the "primary" home pages, since that was (presumably)
- // rendered first (and will be rendered first this time too).
- const ListValue* startup_list =
- user_prefs->GetList(prefs::kDnsPrefetchingStartupList);
-
- if (startup_list) {
- base::ListValue::const_iterator it = startup_list->begin();
- int format_version = -1;
- if (it != startup_list->end() &&
- (*it)->GetAsInteger(&format_version) &&
- format_version == kPredictorStartupFormatVersion) {
- ++it;
- for (; it != startup_list->end(); ++it) {
- std::string url_spec;
- if (!(*it)->GetAsString(&url_spec)) {
- LOG(DFATAL);
- break; // Format incompatibility.
- }
- GURL url(url_spec);
- if (!url.has_host() || !url.has_scheme()) {
- LOG(DFATAL);
- break; // Format incompatibility.
- }
-
- urls.push_back(url);
- }
- }
- }
-
- // Prepare for any static home page(s) the user has in prefs. The user may
- // have a LOT of tab's specified, so we may as well try to warm them all.
- SessionStartupPref tab_start_pref =
- SessionStartupPref::GetStartupPref(user_prefs);
- if (SessionStartupPref::URLS == tab_start_pref.type) {
- for (size_t i = 0; i < tab_start_pref.urls.size(); i++) {
- GURL gurl = tab_start_pref.urls[i];
- if (!gurl.is_valid() || gurl.SchemeIsFile() || gurl.host().empty())
- continue;
- if (gurl.SchemeIs("http") || gurl.SchemeIs("https"))
- urls.push_back(gurl.GetWithEmptyPath());
- }
- }
-
- if (urls.empty())
- urls.push_back(GURL("http://www.google.com:80"));
-
- return urls;
-}
-
-void Predictor::set_max_queueing_delay(int max_queueing_delay_ms) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- g_max_queueing_delay_ms = max_queueing_delay_ms;
-}
-
-void Predictor::set_max_parallel_resolves(size_t max_parallel_resolves) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- g_max_parallel_resolves = max_parallel_resolves;
-}
-
-void Predictor::ShutdownOnUIThread(PrefService* user_prefs) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- SaveStateForNextStartupAndTrim(user_prefs);
-
+void Predictor::PredictFrameSubresources(const GURL& url) {
+ DCHECK_EQ(url.GetWithEmptyPath(), url);
+ // Add one pass through the message loop to allow current navigation to
+ // proceed.
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&Predictor::Shutdown, base::Unretained(this)));
-}
-
-// ---------------------- End UI methods. -------------------------------------
-
-// --------------------- Start IO methods. ------------------------------------
-
-void Predictor::Shutdown() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(!shutdown_);
- shutdown_ = true;
-
- STLDeleteElements(&pending_lookups_);
+ NewRunnableMethod(this, &Predictor::PrepareFrameSubresources, url));
}
-void Predictor::DiscardAllResults() {
+void Predictor::PrepareFrameSubresources(const GURL& url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Delete anything listed so far in this session that shows in about:dns.
- referrers_.clear();
-
-
- // Try to delete anything in our work queue.
- while (!work_queue_.IsEmpty()) {
- // Emulate processing cycle as though host was not found.
- GURL url = work_queue_.Pop();
- UrlInfo* info = &results_[url];
- DCHECK(info->HasUrl(url));
- info->SetAssignedState();
- info->SetNoSuchNameState();
+ DCHECK_EQ(url.GetWithEmptyPath(), url);
+ Referrers::iterator it = referrers_.find(url);
+ if (referrers_.end() == it) {
+ // Only when we don't know anything about this url, make 2 connections
+ // available. We could do this completely via learning (by prepopulating
+ // the referrer_ list with this expected value), but it would swell the
+ // size of the list with all the "Leaf" nodes in the tree (nodes that don't
+ // load any subresources). If we learn about this resource, we will instead
+ // provide a more carefully estimated preconnection count.
+ if (preconnect_enabled_)
+ PreconnectOnIOThread(url, UrlInfo::SELF_REFERAL_MOTIVATED, 2);
+ return;
}
- // Now every result_ is either resolved, or is being resolved
- // (see LookupRequest).
- // Step through result_, recording names of all hosts that can't be erased.
- // We can't erase anything being worked on.
- Results assignees;
- for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
- GURL url(it->first);
- UrlInfo* info = &it->second;
- DCHECK(info->HasUrl(url));
- if (info->is_assigned()) {
- info->SetPendingDeleteState();
- assignees[url] = *info;
+ Referrer* referrer = &(it->second);
+ referrer->IncrementUseCount();
+ const UrlInfo::ResolutionMotivation motivation =
+ UrlInfo::LEARNED_REFERAL_MOTIVATED;
+ for (Referrer::iterator future_url = referrer->begin();
+ future_url != referrer->end(); ++future_url) {
+ SubresourceValue evalution(TOO_NEW);
+ double connection_expectation = future_url->second.subresource_use_rate();
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation",
+ static_cast<int>(connection_expectation * 100),
+ 10, 5000, 50);
+ future_url->second.ReferrerWasObserved();
+ if (preconnect_enabled_ &&
+ connection_expectation > kPreconnectWorthyExpectedValue) {
+ evalution = PRECONNECTION;
+ future_url->second.IncrementPreconnectionCount();
+ int count = static_cast<int>(std::ceil(connection_expectation));
+ if (url.host() == future_url->first.host())
+ ++count;
+ PreconnectOnIOThread(future_url->first, motivation, count);
+ } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) {
+ evalution = PRERESOLUTION;
+ future_url->second.preresolution_increment();
+ UrlInfo* queued_info = AppendToResolutionQueue(future_url->first,
+ motivation);
+ if (queued_info)
+ queued_info->SetReferringHostname(url);
}
+ UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution,
+ SUBRESOURCE_VALUE_MAX);
}
- DCHECK_LE(assignees.size(), max_concurrent_dns_lookups_);
- results_.clear();
- // Put back in the names being worked on.
- for (Results::iterator it = assignees.begin(); assignees.end() != it; ++it) {
- DCHECK(it->second.is_marked_to_delete());
- results_[it->first] = it->second;
- }
-}
-
-// Overloaded Resolve() to take a vector of names.
-void Predictor::ResolveList(const UrlList& urls,
- UrlInfo::ResolutionMotivation motivation) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- for (UrlList::const_iterator it = urls.begin(); it < urls.end(); ++it) {
- AppendToResolutionQueue(*it, motivation);
- }
-}
-
-// Basic Resolve() takes an invidual name, and adds it
-// to the queue.
-void Predictor::Resolve(const GURL& url,
- UrlInfo::ResolutionMotivation motivation) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!url.has_host())
- return;
- AppendToResolutionQueue(url, motivation);
-}
-
-void Predictor::LearnFromNavigation(const GURL& referring_url,
- const GURL& target_url) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!predictor_enabled_)
- return;
- DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url));
- DCHECK_NE(referring_url, GURL::EmptyGURL());
- DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url));
- DCHECK_NE(target_url, GURL::EmptyGURL());
-
- referrers_[referring_url].SuggestHost(target_url);
- // Possibly do some referrer trimming.
- TrimReferrers();
-}
-
-//-----------------------------------------------------------------------------
-// This section supports the about:dns page.
-
-void Predictor::PredictorGetHtmlInfo(Predictor* predictor,
- std::string* output) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- output->append("<html><head><title>About DNS</title>"
- // We'd like the following no-cache... but it doesn't work.
- // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">"
- "</head><body>");
- if (predictor && predictor->predictor_enabled()) {
- predictor->GetHtmlInfo(output);
- } else {
- output->append("DNS pre-resolution and TCP pre-connection is disabled.");
- }
- output->append("</body></html>");
}
// Provide sort order so all .com's are together, etc.
@@ -588,11 +418,6 @@ void Predictor::GetHtmlReferrerLists(std::string* output) {
void Predictor::GetHtmlInfo(std::string* output) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (initial_observer_.get())
- initial_observer_->GetFirstResolutionsHtml(output);
- // Show list of subresource predictions and stats.
- GetHtmlReferrerLists(output);
-
// Local lists for calling UrlInfo
UrlInfo::UrlInfoTable name_not_found;
UrlInfo::UrlInfoTable name_preresolved;
@@ -628,306 +453,81 @@ void Predictor::GetHtmlInfo(std::string* output) {
"Preresolving DNS records revealed non-existence for ", brief, output);
}
-void Predictor::TrimReferrersNow() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Just finish up work if an incremental trim is in progress.
- if (urls_being_trimmed_.empty())
- LoadUrlsForTrimming();
- IncrementalTrimReferrers(true); // Do everything now.
-}
-
-void Predictor::SerializeReferrers(base::ListValue* referral_list) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- referral_list->Clear();
- referral_list->Append(new base::FundamentalValue(PREDICTOR_REFERRER_VERSION));
- for (Referrers::const_iterator it = referrers_.begin();
- it != referrers_.end(); ++it) {
- // Serialize the list of subresource names.
- Value* subresource_list(it->second.Serialize());
-
- // Create a list for each referer.
- ListValue* motivator(new ListValue);
- motivator->Append(new StringValue(it->first.spec()));
- motivator->Append(subresource_list);
-
- referral_list->Append(motivator);
- }
-}
-
-void Predictor::DeserializeReferrers(const base::ListValue& referral_list) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- int format_version = -1;
- if (referral_list.GetSize() > 0 &&
- referral_list.GetInteger(0, &format_version) &&
- format_version == PREDICTOR_REFERRER_VERSION) {
- for (size_t i = 1; i < referral_list.GetSize(); ++i) {
- base::ListValue* motivator;
- if (!referral_list.GetList(i, &motivator)) {
- NOTREACHED();
- return;
- }
- std::string motivating_url_spec;
- if (!motivator->GetString(0, &motivating_url_spec)) {
- NOTREACHED();
- return;
- }
-
- Value* subresource_list;
- if (!motivator->Get(1, &subresource_list)) {
- NOTREACHED();
- return;
- }
-
- referrers_[GURL(motivating_url_spec)].Deserialize(*subresource_list);
- }
- }
-}
-
-void Predictor::DeserializeReferrersThenDelete(
- base::ListValue* referral_list) {
- DeserializeReferrers(*referral_list);
- delete referral_list;
-}
-
-void Predictor::DiscardInitialNavigationHistory() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (initial_observer_.get())
- initial_observer_->DiscardInitialNavigationHistory();
-}
-
-void Predictor::FinalizeInitializationOnIOThread(
- const UrlList& startup_urls,
- base::ListValue* referral_list,
- IOThread* io_thread) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- initial_observer_.reset(new InitialObserver());
- host_resolver_ = io_thread->globals()->host_resolver.get();
-
- // ScopedRunnableMethodFactory instances need to be created and destroyed
- // on the same thread. The predictor lives on the IO thread and will die
- // from there so now that we're on the IO thread we need to properly
- // initialize the ScopedrunnableMethodFactory.
- trim_task_factory_.reset(new ScopedRunnableMethodFactory<Predictor>(this));
-
- // Prefetch these hostnames on startup.
- DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED);
- DeserializeReferrersThenDelete(referral_list);
-}
-
-//-----------------------------------------------------------------------------
-// This section intermingles prefetch results with actual browser HTTP
-// network activity. It supports calculating of the benefit of a prefetch, as
-// well as recording what prefetched hostname resolutions might be potentially
-// helpful during the next chrome-startup.
-//-----------------------------------------------------------------------------
-
-void Predictor::LearnAboutInitialNavigation(const GURL& url) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!predictor_enabled_ || NULL == initial_observer_.get() )
- return;
- initial_observer_->Append(url, this);
-}
-
-// This API is only used in the browser process.
-// It is called from an IPC message originating in the renderer. It currently
-// includes both Page-Scan, and Link-Hover prefetching.
-// TODO(jar): Separate out link-hover prefetching, and page-scan results.
-void Predictor::DnsPrefetchList(const NameList& hostnames) {
- // TODO(jar): Push GURL transport further back into renderer, but this will
- // require a Webkit change in the observer :-/.
- UrlList urls;
- for (NameList::const_iterator it = hostnames.begin();
- it < hostnames.end();
- ++it) {
- urls.push_back(GURL("http://" + *it + ":80"));
- }
-
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DnsPrefetchMotivatedList(urls, UrlInfo::PAGE_SCAN_MOTIVATED);
-}
-
-void Predictor::DnsPrefetchMotivatedList(
- const UrlList& urls,
+UrlInfo* Predictor::AppendToResolutionQueue(
+ const GURL& url,
UrlInfo::ResolutionMotivation motivation) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
- BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!predictor_enabled_)
- return;
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(url.has_host());
- if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- ResolveList(urls, motivation);
- } else {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&Predictor::ResolveList, base::Unretained(this),
- urls, motivation));
- }
-}
+ if (shutdown_)
+ return NULL;
-//-----------------------------------------------------------------------------
-// Functions to handle saving of hostnames from one session to the next, to
-// expedite startup times.
+ UrlInfo* info = &results_[url];
+ info->SetUrl(url); // Initialize or DCHECK.
+ // TODO(jar): I need to discard names that have long since expired.
+ // Currently we only add to the domain map :-/
-static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
- base::ListValue* startup_list,
- base::ListValue* referral_list,
- base::WaitableEvent* completion,
- Predictor* predictor) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(info->HasUrl(url));
- if (NULL == predictor) {
- completion->Signal();
- return;
+ if (!info->NeedsDnsUpdate()) {
+ info->DLogResultsStats("DNS PrefetchNotUpdated");
+ return NULL;
}
- predictor->SaveDnsPrefetchStateForNextStartupAndTrim(
- startup_list, referral_list, completion);
-}
-void Predictor::SaveStateForNextStartupAndTrim(PrefService* prefs) {
- if (!predictor_enabled_)
- return;
-
- base::WaitableEvent completion(true, false);
-
- ListPrefUpdate update_startup_list(prefs, prefs::kDnsPrefetchingStartupList);
- ListPrefUpdate update_referral_list(prefs,
- prefs::kDnsPrefetchingHostReferralList);
- if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
- update_startup_list.Get(),
- update_referral_list.Get(),
- &completion,
- this);
- } else {
- bool posted = BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(
- SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread,
- update_startup_list.Get(),
- update_referral_list.Get(),
- &completion,
- this));
-
- // TODO(jar): Synchronous waiting for the IO thread is a potential source
- // to deadlocks and should be investigated. See http://crbug.com/78451.
- DCHECK(posted);
- if (posted)
- completion.Wait();
- }
+ info->SetQueuedState(motivation);
+ work_queue_.Push(url, motivation);
+ StartSomeQueuedResolutions();
+ return info;
}
-void Predictor::SaveDnsPrefetchStateForNextStartupAndTrim(
- base::ListValue* startup_list,
- base::ListValue* referral_list,
- base::WaitableEvent* completion) {
+void Predictor::StartSomeQueuedResolutions() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (initial_observer_.get())
- initial_observer_->GetInitialDnsResolutionList(startup_list);
-
- // Do at least one trim at shutdown, in case the user wasn't running long
- // enough to do any regular trimming of referrers.
- TrimReferrersNow();
- SerializeReferrers(referral_list);
-
- completion->Signal();
-}
-
-void Predictor::EnablePredictor(bool enable) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
- BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- EnablePredictorOnIOThread(enable);
- } else {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&Predictor::EnablePredictorOnIOThread,
- base::Unretained(this), enable));
- }
-}
+ while (!work_queue_.IsEmpty() &&
+ pending_lookups_.size() < max_concurrent_dns_lookups_) {
+ const GURL url(work_queue_.Pop());
+ UrlInfo* info = &results_[url];
+ DCHECK(info->HasUrl(url));
+ info->SetAssignedState();
-void Predictor::EnablePredictorOnIOThread(bool enable) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- predictor_enabled_ = enable;
-}
+ if (CongestionControlPerformed(info)) {
+ DCHECK(work_queue_.IsEmpty());
+ return;
+ }
-void Predictor::PredictFrameSubresources(const GURL& url) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
- BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!predictor_enabled_)
- return;
- DCHECK_EQ(url.GetWithEmptyPath(), url);
- // Add one pass through the message loop to allow current navigation to
- // proceed.
- if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- PrepareFrameSubresources(url);
- } else {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&Predictor::PrepareFrameSubresources,
- base::Unretained(this), url));
+ LookupRequest* request = new LookupRequest(this, host_resolver_, url);
+ int status = request->Start();
+ if (status == net::ERR_IO_PENDING) {
+ // Will complete asynchronously.
+ pending_lookups_.insert(request);
+ peak_pending_lookups_ = std::max(peak_pending_lookups_,
+ pending_lookups_.size());
+ } else {
+ // Completed synchronously (was already cached by HostResolver), or else
+ // there was (equivalently) some network error that prevents us from
+ // finding the name. Status net::OK means it was "found."
+ LookupFinished(request, url, status == net::OK);
+ delete request;
+ }
}
}
-enum SubresourceValue {
- PRECONNECTION,
- PRERESOLUTION,
- TOO_NEW,
- SUBRESOURCE_VALUE_MAX
-};
-
-void Predictor::PrepareFrameSubresources(const GURL& url) {
+bool Predictor::CongestionControlPerformed(UrlInfo* info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK_EQ(url.GetWithEmptyPath(), url);
- Referrers::iterator it = referrers_.find(url);
- if (referrers_.end() == it) {
- // Only when we don't know anything about this url, make 2 connections
- // available. We could do this completely via learning (by prepopulating
- // the referrer_ list with this expected value), but it would swell the
- // size of the list with all the "Leaf" nodes in the tree (nodes that don't
- // load any subresources). If we learn about this resource, we will instead
- // provide a more carefully estimated preconnection count.
- if (preconnect_enabled_)
- PreconnectOnIOThread(url, UrlInfo::SELF_REFERAL_MOTIVATED, 2);
- return;
- }
-
- Referrer* referrer = &(it->second);
- referrer->IncrementUseCount();
- const UrlInfo::ResolutionMotivation motivation =
- UrlInfo::LEARNED_REFERAL_MOTIVATED;
- for (Referrer::iterator future_url = referrer->begin();
- future_url != referrer->end(); ++future_url) {
- SubresourceValue evalution(TOO_NEW);
- double connection_expectation = future_url->second.subresource_use_rate();
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation",
- static_cast<int>(connection_expectation * 100),
- 10, 5000, 50);
- future_url->second.ReferrerWasObserved();
- if (preconnect_enabled_ &&
- connection_expectation > kPreconnectWorthyExpectedValue) {
- evalution = PRECONNECTION;
- future_url->second.IncrementPreconnectionCount();
- int count = static_cast<int>(std::ceil(connection_expectation));
- if (url.host() == future_url->first.host())
- ++count;
- PreconnectOnIOThread(future_url->first, motivation, count);
- } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) {
- evalution = PRERESOLUTION;
- future_url->second.preresolution_increment();
- UrlInfo* queued_info = AppendToResolutionQueue(future_url->first,
- motivation);
- if (queued_info)
- queued_info->SetReferringHostname(url);
- }
- UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution,
- SUBRESOURCE_VALUE_MAX);
+ // Note: queue_duration is ONLY valid after we go to assigned state.
+ if (info->queue_duration() < max_dns_queue_delay_)
+ return false;
+ // We need to discard all entries in our queue, as we're keeping them waiting
+ // too long. By doing this, we'll have a chance to quickly service urgent
+ // resolutions, and not have a bogged down system.
+ while (true) {
+ info->RemoveFromQueue();
+ if (work_queue_.IsEmpty())
+ break;
+ info = &results_[work_queue_.Pop()];
+ info->SetAssignedState();
}
+ return true;
}
void Predictor::OnLookupFinished(LookupRequest* request, const GURL& url,
@@ -956,79 +556,96 @@ void Predictor::LookupFinished(LookupRequest* request, const GURL& url,
}
}
-UrlInfo* Predictor::AppendToResolutionQueue(
- const GURL& url,
- UrlInfo::ResolutionMotivation motivation) {
+void Predictor::DiscardAllResults() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(url.has_host());
-
- if (shutdown_)
- return NULL;
+ // Delete anything listed so far in this session that shows in about:dns.
+ referrers_.clear();
- UrlInfo* info = &results_[url];
- info->SetUrl(url); // Initialize or DCHECK.
- // TODO(jar): I need to discard names that have long since expired.
- // Currently we only add to the domain map :-/
- DCHECK(info->HasUrl(url));
+ // Try to delete anything in our work queue.
+ while (!work_queue_.IsEmpty()) {
+ // Emulate processing cycle as though host was not found.
+ GURL url = work_queue_.Pop();
+ UrlInfo* info = &results_[url];
+ DCHECK(info->HasUrl(url));
+ info->SetAssignedState();
+ info->SetNoSuchNameState();
+ }
+ // Now every result_ is either resolved, or is being resolved
+ // (see LookupRequest).
- if (!info->NeedsDnsUpdate()) {
- info->DLogResultsStats("DNS PrefetchNotUpdated");
- return NULL;
+ // Step through result_, recording names of all hosts that can't be erased.
+ // We can't erase anything being worked on.
+ Results assignees;
+ for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
+ GURL url(it->first);
+ UrlInfo* info = &it->second;
+ DCHECK(info->HasUrl(url));
+ if (info->is_assigned()) {
+ info->SetPendingDeleteState();
+ assignees[url] = *info;
+ }
+ }
+ DCHECK(assignees.size() <= max_concurrent_dns_lookups_);
+ results_.clear();
+ // Put back in the names being worked on.
+ for (Results::iterator it = assignees.begin(); assignees.end() != it; ++it) {
+ DCHECK(it->second.is_marked_to_delete());
+ results_[it->first] = it->second;
}
+}
- info->SetQueuedState(motivation);
- work_queue_.Push(url, motivation);
- StartSomeQueuedResolutions();
- return info;
+void Predictor::TrimReferrersNow() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Just finish up work if an incremental trim is in progress.
+ if (urls_being_trimmed_.empty())
+ LoadUrlsForTrimming();
+ IncrementalTrimReferrers(true); // Do everything now.
}
-bool Predictor::CongestionControlPerformed(UrlInfo* info) {
+void Predictor::SerializeReferrers(ListValue* referral_list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Note: queue_duration is ONLY valid after we go to assigned state.
- if (info->queue_duration() < max_dns_queue_delay_)
- return false;
- // We need to discard all entries in our queue, as we're keeping them waiting
- // too long. By doing this, we'll have a chance to quickly service urgent
- // resolutions, and not have a bogged down system.
- while (true) {
- info->RemoveFromQueue();
- if (work_queue_.IsEmpty())
- break;
- info = &results_[work_queue_.Pop()];
- info->SetAssignedState();
+ referral_list->Clear();
+ referral_list->Append(new base::FundamentalValue(PREDICTOR_REFERRER_VERSION));
+ for (Referrers::const_iterator it = referrers_.begin();
+ it != referrers_.end(); ++it) {
+ // Serialize the list of subresource names.
+ Value* subresource_list(it->second.Serialize());
+
+ // Create a list for each referer.
+ ListValue* motivator(new ListValue);
+ motivator->Append(new StringValue(it->first.spec()));
+ motivator->Append(subresource_list);
+
+ referral_list->Append(motivator);
}
- return true;
}
-void Predictor::StartSomeQueuedResolutions() {
+void Predictor::DeserializeReferrers(const ListValue& referral_list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ int format_version = -1;
+ if (referral_list.GetSize() > 0 &&
+ referral_list.GetInteger(0, &format_version) &&
+ format_version == PREDICTOR_REFERRER_VERSION) {
+ for (size_t i = 1; i < referral_list.GetSize(); ++i) {
+ ListValue* motivator;
+ if (!referral_list.GetList(i, &motivator)) {
+ NOTREACHED();
+ return;
+ }
+ std::string motivating_url_spec;
+ if (!motivator->GetString(0, &motivating_url_spec)) {
+ NOTREACHED();
+ return;
+ }
- while (!work_queue_.IsEmpty() &&
- pending_lookups_.size() < max_concurrent_dns_lookups_) {
- const GURL url(work_queue_.Pop());
- UrlInfo* info = &results_[url];
- DCHECK(info->HasUrl(url));
- info->SetAssignedState();
-
- if (CongestionControlPerformed(info)) {
- DCHECK(work_queue_.IsEmpty());
- return;
- }
+ Value* subresource_list;
+ if (!motivator->Get(1, &subresource_list)) {
+ NOTREACHED();
+ return;
+ }
- LookupRequest* request = new LookupRequest(this, host_resolver_, url);
- int status = request->Start();
- if (status == net::ERR_IO_PENDING) {
- // Will complete asynchronously.
- pending_lookups_.insert(request);
- peak_pending_lookups_ = std::max(peak_pending_lookups_,
- pending_lookups_.size());
- } else {
- // Completed synchronously (was already cached by HostResolver), or else
- // there was (equivalently) some network error that prevents us from
- // finding the name. Status net::OK means it was "found."
- LookupFinished(request, url, status == net::OK);
- delete request;
+ referrers_[GURL(motivating_url_spec)].Deserialize(*subresource_list);
}
}
}
@@ -1061,8 +678,8 @@ void Predictor::PostIncrementalTrimTask() {
return;
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- trim_task_factory_->NewRunnableMethod(
- &Predictor::IncrementalTrimReferrers, false),
+ trim_task_factory_.NewRunnableMethod(&Predictor::IncrementalTrimReferrers,
+ false),
kDurationBetweenTrimmingIncrements.InMilliseconds());
}
@@ -1081,9 +698,7 @@ void Predictor::IncrementalTrimReferrers(bool trim_all_now) {
PostIncrementalTrimTask();
}
-// ---------------------- End IO methods. -------------------------------------
-
-//-----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
Predictor::HostNameQueue::HostNameQueue() {
}
@@ -1119,69 +734,15 @@ GURL Predictor::HostNameQueue::Pop() {
return url;
}
-//-----------------------------------------------------------------------------
-// Member definitions for InitialObserver class.
-
-Predictor::InitialObserver::InitialObserver() {
-}
-
-Predictor::InitialObserver::~InitialObserver() {
+void Predictor::DeserializeReferrersThenDelete(ListValue* referral_list) {
+ DeserializeReferrers(*referral_list);
+ delete referral_list;
}
-void Predictor::InitialObserver::Append(const GURL& url,
- Predictor* predictor) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // TODO(rlp): Do we really need the predictor check here?
- if (NULL == predictor)
- return;
- if (kStartupResolutionCount <= first_navigations_.size())
- return;
-
- DCHECK(url.SchemeIs("http") || url.SchemeIs("https"));
- DCHECK_EQ(url, Predictor::CanonicalizeUrl(url));
- if (first_navigations_.find(url) == first_navigations_.end())
- first_navigations_[url] = base::TimeTicks::Now();
-}
-
-void Predictor::InitialObserver::GetInitialDnsResolutionList(
- base::ListValue* startup_list) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(startup_list);
- startup_list->Clear();
- DCHECK_EQ(0u, startup_list->GetSize());
- startup_list->Append(
- new base::FundamentalValue(kPredictorStartupFormatVersion));
- for (FirstNavigations::iterator it = first_navigations_.begin();
- it != first_navigations_.end();
- ++it) {
- DCHECK(it->first == Predictor::CanonicalizeUrl(it->first));
- startup_list->Append(new StringValue(it->first.spec()));
- }
-}
-
-void Predictor::InitialObserver::GetFirstResolutionsHtml(
- std::string* output) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- UrlInfo::UrlInfoTable resolution_list;
- {
- for (FirstNavigations::iterator it(first_navigations_.begin());
- it != first_navigations_.end();
- it++) {
- UrlInfo info;
- info.SetUrl(it->first);
- info.set_time(it->second);
- resolution_list.push_back(info);
- }
- }
- UrlInfo::GetHtmlTable(resolution_list,
- "Future startups will prefetch DNS records for ", false, output);
-}
-
-//-----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
// Helper functions
-//-----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
// static
GURL Predictor::CanonicalizeUrl(const GURL& url) {
@@ -1207,8 +768,5 @@ GURL Predictor::CanonicalizeUrl(const GURL& url) {
return GURL(scheme + "://" + url.host() + colon_plus_port);
}
-void SimpleShutdownPredictor::ShutdownOnUIThread(PrefService* user_prefs) {
- SetShutdown(true);
-}
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/predictor.h b/chrome/browser/net/predictor.h
index 89e0184..f1f0bcb 100644
--- a/chrome/browser/net/predictor.h
+++ b/chrome/browser/net/predictor.h
@@ -27,7 +27,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
#include "chrome/browser/net/url_info.h"
#include "chrome/browser/net/referrer.h"
#include "chrome/common/net/predictor_common.h"
@@ -37,97 +37,29 @@ namespace base {
class ListValue;
}
-namespace base {
-class WaitableEvent;
-}
-
namespace net {
class HostResolver;
} // namespace net
-class IOThread;
-class PrefService;
-class Profile;
-
namespace chrome_browser_net {
typedef chrome_common_net::UrlList UrlList;
typedef chrome_common_net::NameList NameList;
typedef std::map<GURL, UrlInfo> Results;
-// Predictor is constructed during Profile construction (on the UI thread),
-// but it is destroyed on the IO thread when ProfileIOData goes away. All of
-// its core state and functionality happens on the IO thread. The only UI
-// methods are initialization / shutdown related (including preconnect
-// initialization), or convenience methods that internally forward calls to
-// the IO thread.
-class Predictor {
+// Note that Predictor is not thread safe, and must only be called from
+// the IO thread. Failure to do so will result in a DCHECK at runtime.
+class Predictor : public base::RefCountedThreadSafe<Predictor> {
public:
// A version number for prefs that are saved. This should be incremented when
// we change the format so that we discard old data.
enum { PREDICTOR_REFERRER_VERSION = 2 };
- // Given that the underlying Chromium resolver defaults to a total maximum of
- // 8 paralell resolutions, we will avoid any chance of starving navigational
- // resolutions by limiting the number of paralell speculative resolutions.
- // This is used in the field trials and testing.
- // TODO(jar): Move this limitation into the resolver.
- static const size_t kMaxSpeculativeParallelResolves;
-
- // To control the congestion avoidance system, we need an estimate of how
- // many speculative requests may arrive at once. Since we currently only
- // keep 8 subresource names for each frame, we'll use that as our basis.
- // Note that when scanning search results lists, we might actually get 10 at
- // a time, and wikipedia can often supply (during a page scan) upwards of 50.
- // In those odd cases, we may discard some of the later speculative requests
- // mistakenly assuming that the resolutions took too long.
- static const int kTypicalSpeculativeGroupSize;
-
- // The next constant specifies an amount of queueing delay that is
- // "too large," and indicative of problems with resolutions (perhaps due to
- // an overloaded router, or such). When we exceed this delay, congestion
- // avoidance will kick in and all speculations in the queue will be discarded.
- static const int kMaxSpeculativeResolveQueueDelayMs;
-
// |max_concurrent| specifies how many concurrent (parallel) prefetches will
// be performed. Host lookups will be issued through |host_resolver|.
- explicit Predictor(bool preconnect_enabled);
-
- virtual ~Predictor();
-
- // This function is used to create a predictor. For testing, we can create
- // a version which does a simpler shutdown.
- static Predictor* CreatePredictor(bool preconnect_enabled,
- bool simple_shutdown);
-
- static void RegisterUserPrefs(PrefService* user_prefs);
-
- // ------------- Start UI thread methods.
-
- void InitNetworkPredictor(PrefService* user_prefs,
- PrefService* local_state,
- IOThread* io_thread);
-
- // The Omnibox has proposed a given url to the user, and if it is a search
- // URL, then it also indicates that this is preconnectable (i.e., we could
- // preconnect to the search server).
- void AnticipateOmniboxUrl(const GURL& url, bool preconnectable);
-
- // Preconnect a URL and all of its subresource domains.
- void PreconnectUrlAndSubresources(const GURL& url);
-
- static UrlList GetPredictedUrlListAtStartup(PrefService* user_prefs,
- PrefService* local_state);
-
- static void set_max_queueing_delay(int max_queueing_delay_ms);
-
- static void set_max_parallel_resolves(size_t max_parallel_resolves);
-
- virtual void ShutdownOnUIThread(PrefService* user_prefs);
-
- // ------------- End UI thread methods.
-
- // ------------- Start IO thread methods.
+ Predictor(net::HostResolver* host_resolver,
+ base::TimeDelta max_queue_delay_ms, size_t max_concurrent,
+ bool preconnect_enabled);
// Cancel pending requests and prevent new ones from being made.
void Shutdown();
@@ -142,8 +74,23 @@ class Predictor {
// Add hostname(s) to the queue for processing.
void ResolveList(const UrlList& urls,
UrlInfo::ResolutionMotivation motivation);
+ void Resolve(const GURL& url,
+ UrlInfo::ResolutionMotivation motivation);
+
+ // Instigate pre-connection to any URLs, or pre-resolution of related host,
+ // that we predict will be needed after this navigation (typically
+ // more-embedded resources on a page). This method will actually post a task
+ // to do the actual work, so as not to jump ahead of the frame navigation that
+ // instigated this activity.
+ void PredictFrameSubresources(const GURL& url);
- void Resolve(const GURL& url, UrlInfo::ResolutionMotivation motivation);
+ // The Omnibox has proposed a given url to the user, and if it is a search
+ // URL, then it also indicates that this is preconnectable (i.e., we could
+ // preconnect to the search server).
+ void AnticipateOmniboxUrl(const GURL& url, bool preconnectable);
+
+ // Preconnect a URL and all of its subresource domains.
+ void PreconnectUrlAndSubresources(const GURL& url);
// Record details of a navigation so that we can preresolve the host name
// ahead of time the next time the users navigates to the indicated host.
@@ -151,14 +98,11 @@ class Predictor {
// canonicalized to not have a path.
void LearnFromNavigation(const GURL& referring_url, const GURL& target_url);
- // When displaying info in about:dns, the following API is called.
- static void PredictorGetHtmlInfo(Predictor* predictor, std::string* output);
-
// Dump HTML table containing list of referrers for about:dns.
void GetHtmlReferrerLists(std::string* output);
// Dump the list of currently known referrer domains and related prefetchable
- // domains for about:dns.
+ // domains.
void GetHtmlInfo(std::string* output);
// Discards any referrer for which all the suggested host names are currently
@@ -180,82 +124,21 @@ class Predictor {
void DeserializeReferrersThenDelete(base::ListValue* referral_list);
- void DiscardInitialNavigationHistory();
-
- void FinalizeInitializationOnIOThread(
- const std::vector<GURL>& urls_to_prefetch,
- base::ListValue* referral_list,
- IOThread* io_thread);
-
- // During startup, we learn what the first N urls visited are, and then
- // resolve the associated hosts ASAP during our next startup.
- void LearnAboutInitialNavigation(const GURL& url);
-
- // Renderer bundles up list and sends to this browser API via IPC.
- // TODO(jar): Use UrlList instead to include port and scheme.
- void DnsPrefetchList(const NameList& hostnames);
-
- // May be called from either the IO or UI thread and will PostTask
- // to the IO thread if necessary.
- void DnsPrefetchMotivatedList(const UrlList& urls,
- UrlInfo::ResolutionMotivation motivation);
-
- // May be called from either the IO or UI thread and will PostTask
- // to the IO thread if necessary.
- void SaveStateForNextStartupAndTrim(PrefService* prefs);
-
- void SaveDnsPrefetchStateForNextStartupAndTrim(
- base::ListValue* startup_list,
- base::ListValue* referral_list,
- base::WaitableEvent* completion);
-
- // May be called from either the IO or UI thread and will PostTask
- // to the IO thread if necessary.
- void EnablePredictor(bool enable);
-
- void EnablePredictorOnIOThread(bool enable);
-
- // ------------- End IO thread methods.
-
- // The following methods may be called on either the IO or UI threads.
-
- // Instigate pre-connection to any URLs, or pre-resolution of related host,
- // that we predict will be needed after this navigation (typically
- // more-embedded resources on a page). This method will actually post a task
- // to do the actual work, so as not to jump ahead of the frame navigation that
- // instigated this activity.
- void PredictFrameSubresources(const GURL& url);
-
- // Put URL in canonical form, including a scheme, host, and port.
- // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url
- // cannot be otherwise canonicalized.
- static GURL CanonicalizeUrl(const GURL& url);
-
- // Used for testing.
- void SetHostResolver(net::HostResolver* host_resolver) {
- host_resolver_ = host_resolver;
- }
- // Used for testing.
+ // For unit test code only.
size_t max_concurrent_dns_lookups() const {
return max_concurrent_dns_lookups_;
}
- // Used for testing.
- void SetShutdown(bool shutdown) {
- shutdown_ = shutdown;
- }
// Flag setting to use preconnection instead of just DNS pre-fetching.
- bool preconnect_enabled() const {
- return preconnect_enabled_;
- }
-
- // Flag setting for whether we are prefetching dns lookups.
- bool predictor_enabled() const {
- return predictor_enabled_;
- }
+ bool preconnect_enabled() const { return preconnect_enabled_; }
+ // Put URL in canonical form, including a scheme, host, and port.
+ // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url
+ // cannot be otherwise canonicalized.
+ static GURL CanonicalizeUrl(const GURL& url);
private:
+ friend class base::RefCountedThreadSafe<Predictor>;
FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest);
FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest);
FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest);
@@ -295,38 +178,6 @@ class Predictor {
DISALLOW_COPY_AND_ASSIGN(HostNameQueue);
};
- // The InitialObserver monitors navigations made by the network stack. This
- // is only used to identify startup time resolutions (for re-resolution
- // during our next process startup).
- // TODO(jar): Consider preconnecting at startup, which may be faster than
- // waiting for render process to start and request a connection.
- class InitialObserver {
- public:
- InitialObserver();
- ~InitialObserver();
- // Recording of when we observed each navigation.
- typedef std::map<GURL, base::TimeTicks> FirstNavigations;
-
- // Potentially add a new URL to our startup list.
- void Append(const GURL& url, Predictor* predictor);
-
- // Get an HTML version of our current planned first_navigations_.
- void GetFirstResolutionsHtml(std::string* output);
-
- // Persist the current first_navigations_ for storage in a list.
- void GetInitialDnsResolutionList(base::ListValue* startup_list);
-
- // Discards all initial loading history.
- void DiscardInitialNavigationHistory() { first_navigations_.clear(); }
-
- private:
- // List of the first N URL resolutions observed in this run.
- FirstNavigations first_navigations_;
-
- // The number of URLs we'll save for pre-resolving at next startup.
- static const size_t kStartupResolutionCount = 10;
- };
-
// A map that is keyed with the host/port that we've learned were the cause
// of loading additional URLs. The list of additional targets is held
// in a Referrer instance, which is a value in this map.
@@ -355,6 +206,13 @@ class Predictor {
// Number of referring URLs processed in an incremental trimming.
static const size_t kUrlsTrimmedPerIncrement;
+ ~Predictor();
+
+ // Perform actual resolution or preconnection to subresources now. This is
+ // an internal worker method that is reached via a post task from
+ // PredictFrameSubresources().
+ void PrepareFrameSubresources(const GURL& url);
+
// Only for testing. Returns true if hostname has been successfully resolved
// (name found).
bool WasFound(const GURL& url) const {
@@ -374,13 +232,6 @@ class Predictor {
// Only for testing;
size_t peak_pending_lookups() const { return peak_pending_lookups_; }
- // ------------- Start IO thread methods.
-
- // Perform actual resolution or preconnection to subresources now. This is
- // an internal worker method that is reached via a post task from
- // PredictFrameSubresources().
- void PrepareFrameSubresources(const GURL& url);
-
// Access method for use by async lookup request to pass resolution result.
void OnLookupFinished(LookupRequest* request, const GURL& url, bool found);
@@ -426,14 +277,6 @@ class Predictor {
// continue with them shortly (i.e., it yeilds and continues).
void IncrementalTrimReferrers(bool trim_all_now);
- // ------------- End IO thread methods.
-
- scoped_ptr<InitialObserver> initial_observer_;
-
- // Status of speculative DNS resolution and speculative TCP/IP connection
- // feature.
- bool predictor_enabled_;
-
// work_queue_ holds a list of names we need to look up.
HostNameQueue work_queue_;
@@ -459,7 +302,7 @@ class Predictor {
const base::TimeDelta max_dns_queue_delay_;
// The host resolver we warm DNS entries for.
- net::HostResolver* host_resolver_;
+ net::HostResolver* const host_resolver_;
// Are we currently using preconnection, rather than just DNS resolution, for
// subresources and omni-box search URLs.
@@ -491,20 +334,11 @@ class Predictor {
// A time after which we need to do more trimming of referrers.
base::TimeTicks next_trim_time_;
- scoped_ptr<ScopedRunnableMethodFactory<Predictor> > trim_task_factory_;
+ ScopedRunnableMethodFactory<Predictor> trim_task_factory_;
DISALLOW_COPY_AND_ASSIGN(Predictor);
};
-// This version of hte predictor is used for testing
-class SimpleShutdownPredictor : public Predictor {
- public:
- explicit SimpleShutdownPredictor(bool preconnect_enabled)
- : Predictor(preconnect_enabled) {}
- virtual ~SimpleShutdownPredictor() {}
- virtual void ShutdownOnUIThread(PrefService* user_prefs);
-};
-
} // namespace chrome_browser_net
#endif // CHROME_BROWSER_NET_PREDICTOR_H_
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc
index e5c7196..58aab26 100644
--- a/chrome/browser/net/predictor_unittest.cc
+++ b/chrome/browser/net/predictor_unittest.cc
@@ -13,7 +13,7 @@
#include "base/string_number_conversions.h"
#include "base/timer.h"
#include "base/values.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/url_info.h"
#include "chrome/common/net/predictor_common.h"
#include "content/browser/browser_thread.h"
@@ -62,9 +62,10 @@ class WaitForResolutionHelper {
class PredictorTest : public testing::Test {
public:
PredictorTest()
- : ui_thread_(BrowserThread::UI, &loop_),
- io_thread_(BrowserThread::IO, &loop_),
- host_resolver_(new net::MockCachingHostResolver()) {
+ : io_thread_(BrowserThread::IO, &loop_),
+ host_resolver_(new net::MockCachingHostResolver()),
+ default_max_queueing_delay_(TimeDelta::FromMilliseconds(
+ PredictorInit::kMaxSpeculativeResolveQueueDelayMs)) {
}
protected:
@@ -72,10 +73,6 @@ class PredictorTest : public testing::Test {
#if defined(OS_WIN)
net::EnsureWinsockInit();
#endif
- Predictor::set_max_parallel_resolves(
- Predictor::kMaxSpeculativeParallelResolves);
- Predictor::set_max_queueing_delay(
- Predictor::kMaxSpeculativeResolveQueueDelayMs);
// Since we are using a caching HostResolver, the following latencies will
// only be incurred by the first request, after which the result will be
// cached internally by |host_resolver_|.
@@ -98,19 +95,26 @@ class PredictorTest : public testing::Test {
// IMPORTANT: do not move this below |host_resolver_|; the host resolver
// must not outlive the message loop, otherwise bad things can happen
// (like posting to a deleted message loop).
- MessageLoopForUI loop_;
- BrowserThread ui_thread_;
+ MessageLoop loop_;
BrowserThread io_thread_;
protected:
scoped_ptr<net::MockCachingHostResolver> host_resolver_;
+
+ // Shorthand to access TimeDelta of PredictorInit::kMaxQueueingDelayMs.
+ // (It would be a static constant... except style rules preclude that :-/ ).
+ const TimeDelta default_max_queueing_delay_;
};
//------------------------------------------------------------------------------
TEST_F(PredictorTest, StartupShutdownTest) {
- Predictor testing_master(true);
- testing_master.Shutdown();
+ scoped_refptr<Predictor> testing_master(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
+ testing_master->Shutdown();
}
@@ -119,22 +123,25 @@ TEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) {
new net::WaitingHostResolverProc(NULL));
host_resolver_->Reset(resolver_proc);
- Predictor testing_master(true);
- testing_master.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> testing_master(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
GURL localhost("http://localhost:80");
UrlList names;
names.push_back(localhost);
- testing_master.ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
+ testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask(), 500);
MessageLoop::current()->Run();
- EXPECT_FALSE(testing_master.WasFound(localhost));
+ EXPECT_FALSE(testing_master->WasFound(localhost));
- testing_master.Shutdown();
+ testing_master->Shutdown();
// Clean up after ourselves.
resolver_proc->Signal();
@@ -142,8 +149,11 @@ TEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) {
}
TEST_F(PredictorTest, SingleLookupTest) {
- Predictor testing_master(true);
- testing_master.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> testing_master(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
GURL goog("http://www.google.com:80");
@@ -152,27 +162,30 @@ TEST_F(PredictorTest, SingleLookupTest) {
// Try to flood the predictor with many concurrent requests.
for (int i = 0; i < 10; i++)
- testing_master.ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
+ testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
- WaitForResolution(&testing_master, names);
+ WaitForResolution(testing_master, names);
- EXPECT_TRUE(testing_master.WasFound(goog));
+ EXPECT_TRUE(testing_master->WasFound(goog));
MessageLoop::current()->RunAllPending();
- EXPECT_GT(testing_master.peak_pending_lookups(), names.size() / 2);
- EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
- EXPECT_LE(testing_master.peak_pending_lookups(),
- testing_master.max_concurrent_dns_lookups());
+ EXPECT_GT(testing_master->peak_pending_lookups(), names.size() / 2);
+ EXPECT_LE(testing_master->peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master->peak_pending_lookups(),
+ testing_master->max_concurrent_dns_lookups());
- testing_master.Shutdown();
+ testing_master->Shutdown();
}
TEST_F(PredictorTest, ConcurrentLookupTest) {
host_resolver_->rules()->AddSimulatedFailure("*.notfound");
- Predictor testing_master(true);
- testing_master.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> testing_master(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
GURL goog("http://www.google.com:80"),
goog2("http://gmail.google.com.com:80"),
@@ -192,34 +205,37 @@ TEST_F(PredictorTest, ConcurrentLookupTest) {
// Try to flood the predictor with many concurrent requests.
for (int i = 0; i < 10; i++)
- testing_master.ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
+ testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
- WaitForResolution(&testing_master, names);
+ WaitForResolution(testing_master, names);
- EXPECT_TRUE(testing_master.WasFound(goog));
- EXPECT_TRUE(testing_master.WasFound(goog3));
- EXPECT_TRUE(testing_master.WasFound(goog2));
- EXPECT_TRUE(testing_master.WasFound(goog4));
- EXPECT_FALSE(testing_master.WasFound(bad1));
- EXPECT_FALSE(testing_master.WasFound(bad2));
+ EXPECT_TRUE(testing_master->WasFound(goog));
+ EXPECT_TRUE(testing_master->WasFound(goog3));
+ EXPECT_TRUE(testing_master->WasFound(goog2));
+ EXPECT_TRUE(testing_master->WasFound(goog4));
+ EXPECT_FALSE(testing_master->WasFound(bad1));
+ EXPECT_FALSE(testing_master->WasFound(bad2));
MessageLoop::current()->RunAllPending();
- EXPECT_FALSE(testing_master.WasFound(bad1));
- EXPECT_FALSE(testing_master.WasFound(bad2));
+ EXPECT_FALSE(testing_master->WasFound(bad1));
+ EXPECT_FALSE(testing_master->WasFound(bad2));
- EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
- EXPECT_LE(testing_master.peak_pending_lookups(),
- testing_master.max_concurrent_dns_lookups());
+ EXPECT_LE(testing_master->peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master->peak_pending_lookups(),
+ testing_master->max_concurrent_dns_lookups());
- testing_master.Shutdown();
+ testing_master->Shutdown();
}
TEST_F(PredictorTest, MassiveConcurrentLookupTest) {
host_resolver_->rules()->AddSimulatedFailure("*.notfound");
- Predictor testing_master(true);
- testing_master.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> testing_master(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
UrlList names;
for (int i = 0; i < 100; i++)
@@ -228,17 +244,17 @@ TEST_F(PredictorTest, MassiveConcurrentLookupTest) {
// Try to flood the predictor with many concurrent requests.
for (int i = 0; i < 10; i++)
- testing_master.ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
+ testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED);
- WaitForResolution(&testing_master, names);
+ WaitForResolution(testing_master, names);
MessageLoop::current()->RunAllPending();
- EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
- EXPECT_LE(testing_master.peak_pending_lookups(),
- testing_master.max_concurrent_dns_lookups());
+ EXPECT_LE(testing_master->peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master->peak_pending_lookups(),
+ testing_master->max_concurrent_dns_lookups());
- testing_master.Shutdown();
+ testing_master->Shutdown();
}
//------------------------------------------------------------------------------
@@ -336,25 +352,30 @@ static bool GetDataFromSerialization(const GURL& motivation,
// Make sure nil referral lists really have no entries, and no latency listed.
TEST_F(PredictorTest, ReferrerSerializationNilTest) {
- Predictor predictor(true);
- predictor.SetHostResolver(host_resolver_.get());
-
+ scoped_refptr<Predictor> predictor(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
scoped_ptr<ListValue> referral_list(NewEmptySerializationList());
- predictor.SerializeReferrers(referral_list.get());
+ predictor->SerializeReferrers(referral_list.get());
EXPECT_EQ(1U, referral_list->GetSize());
EXPECT_FALSE(GetDataFromSerialization(
GURL("http://a.com:79"), GURL("http://b.com:78"),
*referral_list.get(), NULL));
- predictor.Shutdown();
+ predictor->Shutdown();
}
// Make sure that when a serialization list includes a value, that it can be
// deserialized into the database, and can be extracted back out via
// serialization without being changed.
TEST_F(PredictorTest, ReferrerSerializationSingleReferrerTest) {
- Predictor predictor(true);
- predictor.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> predictor(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
const GURL motivation_url("http://www.google.com:91");
const GURL subresource_url("http://icons.google.com:90");
const double kUseRate = 23.4;
@@ -363,17 +384,17 @@ TEST_F(PredictorTest, ReferrerSerializationSingleReferrerTest) {
AddToSerializedList(motivation_url, subresource_url,
kUseRate, referral_list.get());
- predictor.DeserializeReferrers(*referral_list.get());
+ predictor->DeserializeReferrers(*referral_list.get());
ListValue recovered_referral_list;
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
double rate;
EXPECT_TRUE(GetDataFromSerialization(
motivation_url, subresource_url, recovered_referral_list, &rate));
EXPECT_EQ(rate, kUseRate);
- predictor.Shutdown();
+ predictor->Shutdown();
}
// Verify that two floats are within 1% of each other in value.
@@ -388,8 +409,11 @@ TEST_F(PredictorTest, ReferrerSerializationSingleReferrerTest) {
// Make sure the Trim() functionality works as expected.
TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
- Predictor predictor(true);
- predictor.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> predictor(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
GURL motivation_url("http://www.google.com:110");
GURL icon_subresource_url("http://icons.google.com:111");
@@ -403,10 +427,10 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
AddToSerializedList(
motivation_url, img_subresource_url, kRateImg, referral_list.get());
- predictor.DeserializeReferrers(*referral_list.get());
+ predictor->DeserializeReferrers(*referral_list.get());
ListValue recovered_referral_list;
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
double rate;
EXPECT_TRUE(GetDataFromSerialization(
@@ -421,8 +445,8 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
// Each time we Trim 24 times, the user_rate figures should reduce by a factor
// of two, until they are small, and then a trim will delete the whole entry.
for (int i = 0; i < 24; ++i)
- predictor.TrimReferrersNow();
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->TrimReferrersNow();
+ predictor->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
motivation_url, icon_subresource_url, recovered_referral_list, &rate));
@@ -433,8 +457,8 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
EXPECT_SIMILAR(rate, kRateImg / 2);
for (int i = 0; i < 24; ++i)
- predictor.TrimReferrersNow();
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->TrimReferrersNow();
+ predictor->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
motivation_url, icon_subresource_url, recovered_referral_list, &rate));
@@ -444,8 +468,8 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
EXPECT_SIMILAR(rate, kRateImg / 4);
for (int i = 0; i < 24; ++i)
- predictor.TrimReferrersNow();
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->TrimReferrersNow();
+ predictor->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
motivation_url, icon_subresource_url, recovered_referral_list, &rate));
@@ -456,8 +480,8 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
motivation_url, img_subresource_url, recovered_referral_list, &rate));
for (int i = 0; i < 24; ++i)
- predictor.TrimReferrersNow();
- predictor.SerializeReferrers(&recovered_referral_list);
+ predictor->TrimReferrersNow();
+ predictor->SerializeReferrers(&recovered_referral_list);
// Icon is also trimmed away, so entire set gets discarded.
EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_FALSE(GetDataFromSerialization(
@@ -465,7 +489,7 @@ TEST_F(PredictorTest, ReferrerSerializationTrimTest) {
EXPECT_FALSE(GetDataFromSerialization(
motivation_url, img_subresource_url, recovered_referral_list, &rate));
- predictor.Shutdown();
+ predictor->Shutdown();
}
@@ -577,24 +601,27 @@ TEST_F(PredictorTest, CanonicalizeUrl) {
}
TEST_F(PredictorTest, DiscardPredictorResults) {
- Predictor predictor(true);
- predictor.SetHostResolver(host_resolver_.get());
+ scoped_refptr<Predictor> predictor(
+ new Predictor(host_resolver_.get(),
+ default_max_queueing_delay_,
+ PredictorInit::kMaxSpeculativeParallelResolves,
+ false));
ListValue referral_list;
- predictor.SerializeReferrers(&referral_list);
+ predictor->SerializeReferrers(&referral_list);
EXPECT_EQ(1U, referral_list.GetSize());
GURL host_1("http://test_1");
GURL host_2("http://test_2");
- predictor.LearnFromNavigation(host_1, host_2);
+ predictor->LearnFromNavigation(host_1, host_2);
- predictor.SerializeReferrers(&referral_list);
+ predictor->SerializeReferrers(&referral_list);
EXPECT_EQ(2U, referral_list.GetSize());
- predictor.DiscardAllResults();
- predictor.SerializeReferrers(&referral_list);
+ predictor->DiscardAllResults();
+ predictor->SerializeReferrers(&referral_list);
EXPECT_EQ(1U, referral_list.GetSize());
- predictor.Shutdown();
+ predictor->Shutdown();
}
} // namespace chrome_browser_net
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index fc9343e..3307aa1 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -27,7 +27,7 @@
#include "chrome/browser/metrics/metrics_log.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/net/net_pref_observer.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/pref_proxy_config_service.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
@@ -145,7 +145,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
BookmarkModel::RegisterUserPrefs(user_prefs);
Browser::RegisterUserPrefs(user_prefs);
PasswordManager::RegisterUserPrefs(user_prefs);
- chrome_browser_net::Predictor::RegisterUserPrefs(user_prefs);
+ chrome_browser_net::RegisterUserPrefs(user_prefs);
DownloadPrefs::RegisterUserPrefs(user_prefs);
bookmark_utils::RegisterUserPrefs(user_prefs);
TabContentsWrapper::RegisterUserPrefs(user_prefs);
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index fe1ac1d..6020735 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -877,7 +877,3 @@ Profile* Profile::CreateOffTheRecordProfile() {
#endif
return new OffTheRecordProfileImpl(this);
}
-
-chrome_browser_net::Predictor* Profile::GetNetworkPredictor() {
- return NULL;
-}
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index fc3eedc..3165b33 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -48,10 +48,6 @@ namespace speech_input {
class SpeechRecognizer;
}
-namespace chrome_browser_net {
-class Predictor;
-}
-
class AutocompleteClassifier;
class BookmarkModel;
class BrowserSignin;
@@ -555,8 +551,6 @@ class Profile : public content::BrowserContext {
// Creates an OffTheRecordProfile which points to this Profile.
Profile* CreateOffTheRecordProfile();
- virtual chrome_browser_net::Predictor* GetNetworkPredictor();
-
protected:
friend class OffTheRecordProfileImpl;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 42e574a..7790c47 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -47,7 +47,6 @@
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/gaia/token_service.h"
#include "chrome/browser/net/net_pref_observer.h"
-#include "chrome/browser/net/predictor.h"
#include "chrome/browser/net/pref_proxy_config_service.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/password_manager/password_store_default.h"
@@ -307,8 +306,7 @@ ProfileImpl::ProfileImpl(const FilePath& path,
#if defined(OS_WIN)
checked_instant_promo_(false),
#endif
- delegate_(delegate),
- predictor_(NULL) {
+ delegate_(delegate) {
DCHECK(!path.empty()) << "Using an empty path will attempt to write " <<
"profile files to the root directory!";
@@ -316,13 +314,6 @@ ProfileImpl::ProfileImpl(const FilePath& path,
TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this,
&ProfileImpl::EnsureSessionServiceCreated);
- // Determine if prefetch is enabled for this profile.
- // If not profile_manager is present, it means we are in a unittest.
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
- predictor_ = chrome_browser_net::Predictor::CreatePredictor(
- !command_line->HasSwitch(switches::kDisablePreconnect),
- g_browser_process->profile_manager() == NULL);
-
if (delegate_) {
prefs_.reset(PrefService::CreatePrefService(
GetPrefFilePath(),
@@ -443,12 +434,9 @@ void ProfileImpl::DoFinalInit() {
// Make sure we initialize the ProfileIOData after everything else has been
// initialized that we might be reading from the IO thread.
-
io_data_.Init(cookie_path, origin_bound_cert_path, cache_path,
cache_max_size, media_cache_path, media_cache_max_size,
- extensions_cookie_path, app_path, predictor_,
- g_browser_process->local_state(),
- g_browser_process->io_thread());
+ extensions_cookie_path, app_path);
// Creation has been finished.
if (delegate_)
@@ -907,7 +895,7 @@ void ProfileImpl::OnPrefsLoaded(bool success) {
DCHECK(!net_pref_observer_.get());
net_pref_observer_.reset(
- new NetPrefObserver(prefs_.get(), GetPrerenderManager(), predictor_));
+ new NetPrefObserver(prefs_.get(), GetPrerenderManager()));
DoFinalInit();
}
@@ -1730,10 +1718,6 @@ prerender::PrerenderManager* ProfileImpl::GetPrerenderManager() {
return prerender_manager_.get();
}
-chrome_browser_net::Predictor* ProfileImpl::GetNetworkPredictor() {
- return predictor_;
-}
-
SpellCheckProfile* ProfileImpl::GetSpellCheckProfile() {
if (!spellcheck_profile_.get())
spellcheck_profile_.reset(new SpellCheckProfile());
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index be71059..aa1fee1 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -124,7 +124,6 @@ class ProfileImpl : public Profile,
virtual PromoCounter* GetInstantPromoCounter();
virtual BrowserSignin* GetBrowserSignin();
virtual ChromeURLDataManager* GetChromeURLDataManager();
- virtual chrome_browser_net::Predictor* GetNetworkPredictor();
#if defined(OS_CHROMEOS)
virtual void ChangeAppLocale(const std::string& locale, AppLocaleChangedVia);
@@ -294,8 +293,6 @@ class ProfileImpl : public Profile,
Profile::Delegate* delegate_;
- chrome_browser_net::Predictor* predictor_;
-
DISALLOW_COPY_AND_ASSIGN(ProfileImpl);
};
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index b1698f4..37ed4d1 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -12,8 +12,6 @@
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/net/chrome_network_delegate.h"
-#include "chrome/browser/net/connect_interceptor.h"
-#include "chrome/browser/net/predictor.h"
#include "chrome/browser/net/sqlite_origin_bound_cert_store.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "chrome/browser/prefs/pref_member.h"
@@ -27,7 +25,6 @@
#include "net/base/origin_bound_cert_service.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/http/http_cache.h"
-#include "net/url_request/url_request_job_factory.h"
ProfileImplIOData::Handle::Handle(Profile* profile)
: io_data_(new ProfileImplIOData),
@@ -46,8 +43,6 @@ ProfileImplIOData::Handle::~Handle() {
if (extensions_request_context_getter_)
extensions_request_context_getter_->CleanupOnUIThread();
- io_data_->predictor_->ShutdownOnUIThread(profile_->GetPrefs());
-
// Clean up all isolated app request contexts.
for (ChromeURLRequestContextGetterMap::iterator iter =
app_request_context_getter_map_.begin();
@@ -59,22 +54,16 @@ ProfileImplIOData::Handle::~Handle() {
io_data_->ShutdownOnUIThread();
}
-void ProfileImplIOData::Handle::Init(
- const FilePath& cookie_path,
- const FilePath& origin_bound_cert_path,
- const FilePath& cache_path,
- int cache_max_size,
- const FilePath& media_cache_path,
- int media_cache_max_size,
- const FilePath& extensions_cookie_path,
- const FilePath& app_path,
- chrome_browser_net::Predictor* predictor,
- PrefService* local_state,
- IOThread* io_thread) {
+void ProfileImplIOData::Handle::Init(const FilePath& cookie_path,
+ const FilePath& origin_bound_cert_path,
+ const FilePath& cache_path,
+ int cache_max_size,
+ const FilePath& media_cache_path,
+ int media_cache_max_size,
+ const FilePath& extensions_cookie_path,
+ const FilePath& app_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!io_data_->lazy_params_.get());
- DCHECK(predictor);
-
LazyParams* lazy_params = new LazyParams;
lazy_params->cookie_path = cookie_path;
@@ -89,11 +78,6 @@ void ProfileImplIOData::Handle::Init(
// Keep track of isolated app path separately so we can use it on demand.
io_data_->app_path_ = app_path;
-
- io_data_->predictor_.reset(predictor);
- io_data_->predictor_->InitNetworkPredictor(profile_->GetPrefs(),
- local_state,
- io_thread);
}
base::Callback<ChromeURLDataManagerBackend*(void)>
@@ -352,9 +336,6 @@ void ProfileImplIOData::LazyInitializeInternal(
media_request_context_->set_job_factory(job_factory());
extensions_context->set_job_factory(job_factory());
- job_factory()->AddInterceptor(
- new chrome_browser_net::ConnectInterceptor(predictor_.get()));
-
lazy_params_.reset();
}
diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h
index e0f61ff..6a5f531 100644
--- a/chrome/browser/profiles/profile_impl_io_data.h
+++ b/chrome/browser/profiles/profile_impl_io_data.h
@@ -12,10 +12,6 @@
#include "base/memory/ref_counted.h"
#include "chrome/browser/profiles/profile_io_data.h"
-namespace chrome_browser_net {
-class Predictor;
-}
-
namespace net {
class HttpTransactionFactory;
} // namespace net
@@ -40,10 +36,7 @@ class ProfileImplIOData : public ProfileIOData {
const FilePath& media_cache_path,
int media_cache_max_size,
const FilePath& extensions_cookie_path,
- const FilePath& app_path,
- chrome_browser_net::Predictor* predictor,
- PrefService* local_state,
- IOThread* io_thread);
+ const FilePath& app_path);
base::Callback<ChromeURLDataManagerBackend*(void)>
GetChromeURLDataManagerBackendGetter() const;
@@ -134,8 +127,6 @@ class ProfileImplIOData : public ProfileIOData {
mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
mutable scoped_ptr<net::HttpTransactionFactory> media_http_factory_;
- mutable scoped_ptr<chrome_browser_net::Predictor> predictor_;
-
// Parameters needed for isolated apps.
FilePath app_path_;
mutable bool clear_local_state_on_exit_;
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index 0c90d4b..5cc1293 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -17,7 +17,7 @@
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/nacl_host/nacl_process_host.h"
#include "chrome/browser/net/chrome_url_request_context.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/task_manager.h"
@@ -191,8 +191,7 @@ void ChromeRenderMessageFilter::OnLaunchNaCl(
void ChromeRenderMessageFilter::OnDnsPrefetch(
const std::vector<std::string>& hostnames) {
- if (profile_->GetNetworkPredictor())
- profile_->GetNetworkPredictor()->DnsPrefetchList(hostnames);
+ chrome_browser_net::DnsPrefetchList(hostnames);
}
void ChromeRenderMessageFilter::OnRendererHistograms(
@@ -521,9 +520,7 @@ void ChromeRenderMessageFilter::OnCanTriggerClipboardWrite(const GURL& url,
void ChromeRenderMessageFilter::OnClearPredictorCache(int* result) {
// This function is disabled unless the user has enabled
// benchmarking extensions.
- chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
- if (predictor)
- predictor->DiscardAllResults();
+ chrome_browser_net::ClearPredictorCache();
*result = 0;
}
diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
index 05347ac..20eb5a5 100644
--- a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
+++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
@@ -7,7 +7,7 @@
#include "base/command_line.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
@@ -24,9 +24,8 @@
#include "content/common/view_messages.h"
ChromeRenderViewHostObserver::ChromeRenderViewHostObserver(
- RenderViewHost* render_view_host, chrome_browser_net::Predictor* predictor)
- : RenderViewHostObserver(render_view_host),
- predictor_(predictor) {
+ RenderViewHost* render_view_host)
+ : RenderViewHostObserver(render_view_host) {
InitRenderViewHostForExtensions();
}
@@ -40,11 +39,9 @@ void ChromeRenderViewHostObserver::RenderViewHostInitialized() {
void ChromeRenderViewHostObserver::Navigate(
const ViewMsg_Navigate_Params& params) {
const GURL& url = params.url;
- if (!predictor_)
- return;
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame) &&
- (url.SchemeIs(chrome::kHttpScheme) || url.SchemeIs(chrome::kHttpsScheme)))
- predictor_->PreconnectUrlAndSubresources(url);
+ (url.SchemeIs(chrome::kHttpScheme) || url.SchemeIs(chrome::kHttpsScheme)))
+ chrome_browser_net::PreconnectUrlAndSubresources(url);
}
bool ChromeRenderViewHostObserver::OnMessageReceived(
diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.h b/chrome/browser/renderer_host/chrome_render_view_host_observer.h
index 5a5eaa8..411a953 100644
--- a/chrome/browser/renderer_host/chrome_render_view_host_observer.h
+++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.h
@@ -8,18 +8,13 @@
#include "content/browser/renderer_host/render_view_host_observer.h"
-namespace chrome_browser_net {
-class Predictor;
-}
-
class Extension;
// This class holds the Chrome specific parts of RenderViewHost, and has the
// same lifetime.
class ChromeRenderViewHostObserver : public RenderViewHostObserver {
public:
- ChromeRenderViewHostObserver(RenderViewHost* render_view_host,
- chrome_browser_net::Predictor* predictor);
+ explicit ChromeRenderViewHostObserver(RenderViewHost* render_view_host);
virtual ~ChromeRenderViewHostObserver();
// RenderViewHostObserver overrides.
@@ -40,8 +35,6 @@ class ChromeRenderViewHostObserver : public RenderViewHostObserver {
void OnDomOperationResponse(const std::string& json_string,
int automation_id);
- chrome_browser_net::Predictor* predictor_;
-
DISALLOW_COPY_AND_ASSIGN(ChromeRenderViewHostObserver);
};
diff --git a/chrome/browser/ui/browser_init.cc b/chrome/browser/ui/browser_init.cc
index 41f533c..9e26e58 100644
--- a/chrome/browser/ui/browser_init.cc
+++ b/chrome/browser/ui/browser_init.cc
@@ -30,7 +30,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/pack_extension_job.h"
#include "chrome/browser/first_run/first_run.h"
-#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -667,10 +667,8 @@ bool BrowserInit::LaunchWithProfile::Launch(
if (command_line_.HasSwitch(switches::kDnsLogDetails))
chrome_browser_net::EnablePredictorDetailedLog(true);
- if (command_line_.HasSwitch(switches::kDnsPrefetchDisable) &&
- profile->GetNetworkPredictor()) {
- profile->GetNetworkPredictor()->EnablePredictor(false);
- }
+ if (command_line_.HasSwitch(switches::kDnsPrefetchDisable))
+ chrome_browser_net::EnablePredictor(false);
if (command_line_.HasSwitch(switches::kDumpHistogramsOnExit))
base::StatisticsRecorder::set_dump_on_exit(true);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ca15603..d5439de 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1502,6 +1502,8 @@
'browser/net/preconnect.h',
'browser/net/predictor.cc',
'browser/net/predictor.h',
+ 'browser/net/predictor_api.cc',
+ 'browser/net/predictor_api.h',
'browser/net/pref_proxy_config_service.cc',
'browser/net/pref_proxy_config_service.h',
'browser/net/proxy_service_factory.cc',
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index c66b022..5eaf2bdb 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -178,6 +178,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
friend class appcache::AppCacheInterceptor;
friend class appcache::AppCacheRequestHandlerTest;
friend class appcache::AppCacheURLRequestJobTest;
+ friend class chrome_browser_net::ConnectInterceptor;
friend class fileapi::FileSystemDirURLRequestJobTest;
friend class fileapi::FileSystemOperationWriteTest;
friend class fileapi::FileSystemURLRequestJobTest;