Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // A Predictor object is instantiated once in the browser process, and manages
      6 // both preresolution of hostnames, as well as TCP/IP preconnection to expected
      7 // subresources.
      8 // Most hostname lists are provided by the renderer processes, and include URLs
      9 // that *might* be used in the near future by the browsing user.  One goal of
     10 // this class is to cause the underlying DNS structure to lookup a hostname
     11 // before it is really needed, and hence reduce latency in the standard lookup
     12 // paths.
     13 // Subresource relationships are usually acquired from the referrer field in a
     14 // navigation.  A subresource URL may be associated with a referrer URL.  Later
     15 // navigations may, if the likelihood of needing the subresource is high enough,
     16 // cause this module to speculatively create a TCP/IP connection. If there is
     17 // only a low likelihood, then a DNS pre-resolution operation may be performed.
     18 
     19 #ifndef CHROME_BROWSER_NET_PREDICTOR_H_
     20 #define CHROME_BROWSER_NET_PREDICTOR_H_
     21 
     22 #include <map>
     23 #include <queue>
     24 #include <set>
     25 #include <string>
     26 #include <vector>
     27 
     28 #include "base/gtest_prod_util.h"
     29 #include "base/memory/scoped_ptr.h"
     30 #include "base/memory/weak_ptr.h"
     31 #include "chrome/browser/net/referrer.h"
     32 #include "chrome/browser/net/spdyproxy/proxy_advisor.h"
     33 #include "chrome/browser/net/timed_cache.h"
     34 #include "chrome/browser/net/url_info.h"
     35 #include "chrome/common/net/predictor_common.h"
     36 #include "net/base/host_port_pair.h"
     37 
     38 class IOThread;
     39 class PrefService;
     40 class Profile;
     41 
     42 namespace base {
     43 class ListValue;
     44 class WaitableEvent;
     45 }
     46 
     47 namespace net {
     48 class HostResolver;
     49 class SSLConfigService;
     50 class TransportSecurityState;
     51 class URLRequestContextGetter;
     52 }
     53 
     54 namespace user_prefs {
     55 class PrefRegistrySyncable;
     56 }
     57 
     58 namespace chrome_browser_net {
     59 
     60 typedef chrome_common_net::UrlList UrlList;
     61 typedef chrome_common_net::NameList NameList;
     62 typedef std::map<GURL, UrlInfo> Results;
     63 
     64 // An observer for testing.
     65 class PredictorObserver {
     66  public:
     67   virtual ~PredictorObserver() {}
     68 
     69   virtual void OnPreconnectUrl(const GURL& original_url,
     70                                const GURL& first_party_for_cookies,
     71                                UrlInfo::ResolutionMotivation motivation,
     72                                int count) = 0;
     73 };
     74 
     75 // Predictor is constructed during Profile construction (on the UI thread),
     76 // but it is destroyed on the IO thread when ProfileIOData goes away. All of
     77 // its core state and functionality happens on the IO thread. The only UI
     78 // methods are initialization / shutdown related (including preconnect
     79 // initialization), or convenience methods that internally forward calls to
     80 // the IO thread.
     81 class Predictor {
     82  public:
     83   // Enum describing when to allow network predictions based on connection type.
     84   // The same enum must be used by the platform-dependent components.
     85   // TODO(bnc): implement as per crbug.com/334602.
     86   enum NetworkPredictionOptions {
     87     NETWORK_PREDICTION_ALWAYS,
     88     NETWORK_PREDICTION_WIFI_ONLY,
     89     NETWORK_PREDICTION_NEVER
     90   };
     91 
     92   // A version number for prefs that are saved. This should be incremented when
     93   // we change the format so that we discard old data.
     94   static const int kPredictorReferrerVersion;
     95 
     96   // Given that the underlying Chromium resolver defaults to a total maximum of
     97   // 8 paralell resolutions, we will avoid any chance of starving navigational
     98   // resolutions by limiting the number of paralell speculative resolutions.
     99   // This is used in the field trials and testing.
    100   // TODO(jar): Move this limitation into the resolver.
    101   static const size_t kMaxSpeculativeParallelResolves;
    102 
    103   // To control the congestion avoidance system, we need an estimate of how
    104   // many speculative requests may arrive at once.  Since we currently only
    105   // keep 8 subresource names for each frame, we'll use that as our basis.
    106   // Note that when scanning search results lists, we might actually get 10 at
    107   // a time, and wikipedia can often supply (during a page scan) upwards of 50.
    108   // In those odd cases, we may discard some of the later speculative requests
    109   // mistakenly assuming that the resolutions took too long.
    110   static const int kTypicalSpeculativeGroupSize;
    111 
    112   // The next constant specifies an amount of queueing delay that is
    113   // "too large," and indicative of problems with resolutions (perhaps due to
    114   // an overloaded router, or such).  When we exceed this delay, congestion
    115   // avoidance will kick in and all speculations in the queue will be discarded.
    116   static const int kMaxSpeculativeResolveQueueDelayMs;
    117 
    118   // We don't bother learning to preconnect via a GET if the original URL
    119   // navigation was so long ago, that a preconnection would have been dropped
    120   // anyway.  We believe most servers will drop the connection in 10 seconds, so
    121   // we currently estimate this time-till-drop at 10 seconds.
    122   // TODO(jar): We should do a persistent field trial to validate/optimize this.
    123   static const int kMaxUnusedSocketLifetimeSecondsWithoutAGet;
    124 
    125   // |max_concurrent| specifies how many concurrent (parallel) prefetches will
    126   // be performed. Host lookups will be issued through |host_resolver|.
    127   explicit Predictor(bool preconnect_enabled);
    128 
    129   virtual ~Predictor();
    130 
    131   // This function is used to create a predictor. For testing, we can create
    132   // a version which does a simpler shutdown.
    133   static Predictor* CreatePredictor(bool preconnect_enabled,
    134                                     bool simple_shutdown);
    135 
    136   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
    137 
    138   // ------------- Start UI thread methods.
    139 
    140   virtual void InitNetworkPredictor(PrefService* user_prefs,
    141                                     PrefService* local_state,
    142                                     IOThread* io_thread,
    143                                     net::URLRequestContextGetter* getter);
    144 
    145   // The Omnibox has proposed a given url to the user, and if it is a search
    146   // URL, then it also indicates that this is preconnectable (i.e., we could
    147   // preconnect to the search server).
    148   void AnticipateOmniboxUrl(const GURL& url, bool preconnectable);
    149 
    150   // Preconnect a URL and all of its subresource domains.
    151   void PreconnectUrlAndSubresources(const GURL& url,
    152                                     const GURL& first_party_for_cookies);
    153 
    154   static UrlList GetPredictedUrlListAtStartup(PrefService* user_prefs,
    155                                               PrefService* local_state);
    156 
    157   static void set_max_queueing_delay(int max_queueing_delay_ms);
    158 
    159   static void set_max_parallel_resolves(size_t max_parallel_resolves);
    160 
    161   virtual void ShutdownOnUIThread();
    162 
    163   // ------------- End UI thread methods.
    164 
    165   // ------------- Start IO thread methods.
    166 
    167   // Cancel pending requests and prevent new ones from being made.
    168   void Shutdown();
    169 
    170   // In some circumstances, for privacy reasons, all results should be
    171   // discarded.  This method gracefully handles that activity.
    172   // Destroy all our internal state, which shows what names we've looked up, and
    173   // how long each has taken, etc. etc.  We also destroy records of suggesses
    174   // (cache hits etc.).
    175   void DiscardAllResults();
    176 
    177   // Add hostname(s) to the queue for processing.
    178   void ResolveList(const UrlList& urls,
    179                    UrlInfo::ResolutionMotivation motivation);
    180 
    181   void Resolve(const GURL& url, UrlInfo::ResolutionMotivation motivation);
    182 
    183   // Record details of a navigation so that we can preresolve the host name
    184   // ahead of time the next time the users navigates to the indicated host.
    185   // Should only be called when urls are distinct, and they should already be
    186   // canonicalized to not have a path.
    187   void LearnFromNavigation(const GURL& referring_url, const GURL& target_url);
    188 
    189   // When displaying info in about:dns, the following API is called.
    190   static void PredictorGetHtmlInfo(Predictor* predictor, std::string* output);
    191 
    192   // Dump HTML table containing list of referrers for about:dns.
    193   void GetHtmlReferrerLists(std::string* output);
    194 
    195   // Dump the list of currently known referrer domains and related prefetchable
    196   // domains for about:dns.
    197   void GetHtmlInfo(std::string* output);
    198 
    199   // Discards any referrer for which all the suggested host names are currently
    200   // annotated with negligible expected-use.  Scales down (diminishes) the
    201   // expected-use of those that remain, so that their use will go down by a
    202   // factor each time we trim (moving the referrer closer to being discarded in
    203   // a future call).
    204   // The task is performed synchronously and completes before returing.
    205   void TrimReferrersNow();
    206 
    207   // Construct a ListValue object that contains all the data in the referrers_
    208   // so that it can be persisted in a pref.
    209   void SerializeReferrers(base::ListValue* referral_list);
    210 
    211   // Process a ListValue that contains all the data from a previous reference
    212   // list, as constructed by SerializeReferrers(), and add all the identified
    213   // values into the current referrer list.
    214   void DeserializeReferrers(const base::ListValue& referral_list);
    215 
    216   void DeserializeReferrersThenDelete(base::ListValue* referral_list);
    217 
    218   void DiscardInitialNavigationHistory();
    219 
    220   void FinalizeInitializationOnIOThread(
    221       const std::vector<GURL>& urls_to_prefetch,
    222       base::ListValue* referral_list,
    223       IOThread* io_thread,
    224       bool predictor_enabled);
    225 
    226   // During startup, we learn what the first N urls visited are, and then
    227   // resolve the associated hosts ASAP during our next startup.
    228   void LearnAboutInitialNavigation(const GURL& url);
    229 
    230   // Renderer bundles up list and sends to this browser API via IPC.
    231   // TODO(jar): Use UrlList instead to include port and scheme.
    232   void DnsPrefetchList(const NameList& hostnames);
    233 
    234   // May be called from either the IO or UI thread and will PostTask
    235   // to the IO thread if necessary.
    236   void DnsPrefetchMotivatedList(const UrlList& urls,
    237                                 UrlInfo::ResolutionMotivation motivation);
    238 
    239   // May be called from either the IO or UI thread and will PostTask
    240   // to the IO thread if necessary.
    241   void SaveStateForNextStartupAndTrim(PrefService* prefs);
    242 
    243   void SaveDnsPrefetchStateForNextStartupAndTrim(
    244       base::ListValue* startup_list,
    245       base::ListValue* referral_list,
    246       base::WaitableEvent* completion);
    247 
    248   // May be called from either the IO or UI thread and will PostTask
    249   // to the IO thread if necessary.
    250   void EnablePredictor(bool enable);
    251 
    252   void EnablePredictorOnIOThread(bool enable);
    253 
    254   // May be called from either the IO or UI thread and will PostTask
    255   // to the IO thread if necessary.
    256   void PreconnectUrl(const GURL& url, const GURL& first_party_for_cookies,
    257                      UrlInfo::ResolutionMotivation motivation, int count);
    258 
    259   void PreconnectUrlOnIOThread(const GURL& url,
    260                                const GURL& first_party_for_cookies,
    261                                UrlInfo::ResolutionMotivation motivation,
    262                                int count);
    263 
    264   void RecordPreconnectTrigger(const GURL& url);
    265 
    266   void RecordPreconnectNavigationStat(const std::vector<GURL>& url_chain,
    267                                       bool is_subresource);
    268 
    269   void RecordLinkNavigation(const GURL& url);
    270 
    271   // ------------- End IO thread methods.
    272 
    273   // The following methods may be called on either the IO or UI threads.
    274 
    275   // Instigate pre-connection to any URLs, or pre-resolution of related host,
    276   // that we predict will be needed after this navigation (typically
    277   // more-embedded resources on a page).  This method will actually post a task
    278   // to do the actual work, so as not to jump ahead of the frame navigation that
    279   // instigated this activity.
    280   void PredictFrameSubresources(const GURL& url,
    281                                 const GURL& first_party_for_cookies);
    282 
    283   // Put URL in canonical form, including a scheme, host, and port.
    284   // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url
    285   // cannot be otherwise canonicalized.
    286   static GURL CanonicalizeUrl(const GURL& url);
    287 
    288   // Used for testing.
    289   void SetHostResolver(net::HostResolver* host_resolver) {
    290     host_resolver_ = host_resolver;
    291   }
    292   // Used for testing.
    293   void SetTransportSecurityState(
    294       net::TransportSecurityState* transport_security_state) {
    295     transport_security_state_ = transport_security_state;
    296   }
    297   // Used for testing.
    298   void SetProxyAdvisor(ProxyAdvisor* proxy_advisor) {
    299     proxy_advisor_.reset(proxy_advisor);
    300   }
    301   // Used for testing.
    302   size_t max_concurrent_dns_lookups() const {
    303     return max_concurrent_dns_lookups_;
    304   }
    305   // Used for testing.
    306   void SetShutdown(bool shutdown) {
    307     shutdown_ = shutdown;
    308   }
    309   // Used for testing.
    310   void SetObserver(PredictorObserver* observer) {
    311     observer_ = observer;
    312   }
    313 
    314   // Flag setting to use preconnection instead of just DNS pre-fetching.
    315   bool preconnect_enabled() const {
    316     return preconnect_enabled_;
    317   }
    318 
    319   // Flag setting for whether we are prefetching dns lookups.
    320   bool predictor_enabled() const {
    321     return predictor_enabled_;
    322   }
    323 
    324 
    325  private:
    326   FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest);
    327   FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest);
    328   FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest);
    329   FRIEND_TEST_ALL_PREFIXES(PredictorTest, ConcurrentLookupTest);
    330   FRIEND_TEST_ALL_PREFIXES(PredictorTest, MassiveConcurrentLookupTest);
    331   FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueuePushPopTest);
    332   FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueueReorderTest);
    333   FRIEND_TEST_ALL_PREFIXES(PredictorTest, ReferrerSerializationTrimTest);
    334   FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTestWithDisabledAdvisor);
    335   FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTestWithEnabledAdvisor);
    336   FRIEND_TEST_ALL_PREFIXES(PredictorTest, TestSimplePreconnectAdvisor);
    337   friend class WaitForResolutionHelper;  // For testing.
    338 
    339   class LookupRequest;
    340 
    341   // A simple priority queue for handling host names.
    342   // Some names that are queued up have |motivation| that requires very rapid
    343   // handling.  For example, a sub-resource name lookup MUST be done before the
    344   // actual sub-resource is fetched.  In contrast, a name that was speculatively
    345   // noted in a page has to be resolved before the user "gets around to"
    346   // clicking on a link.  By tagging (with a motivation) each push we make into
    347   // this FIFO queue, the queue can re-order the more important names to service
    348   // them sooner (relative to some low priority background resolutions).
    349   class HostNameQueue {
    350    public:
    351     HostNameQueue();
    352     ~HostNameQueue();
    353     void Push(const GURL& url,
    354               UrlInfo::ResolutionMotivation motivation);
    355     bool IsEmpty() const;
    356     GURL Pop();
    357 
    358    private:
    359     // The names in the queue that should be serviced (popped) ASAP.
    360     std::queue<GURL> rush_queue_;
    361     // The names in the queue that should only be serviced when rush_queue is
    362     // empty.
    363     std::queue<GURL> background_queue_;
    364 
    365   DISALLOW_COPY_AND_ASSIGN(HostNameQueue);
    366   };
    367 
    368   // The InitialObserver monitors navigations made by the network stack. This
    369   // is only used to identify startup time resolutions (for re-resolution
    370   // during our next process startup).
    371   // TODO(jar): Consider preconnecting at startup, which may be faster than
    372   // waiting for render process to start and request a connection.
    373   class InitialObserver {
    374    public:
    375     InitialObserver();
    376     ~InitialObserver();
    377     // Recording of when we observed each navigation.
    378     typedef std::map<GURL, base::TimeTicks> FirstNavigations;
    379 
    380     // Potentially add a new URL to our startup list.
    381     void Append(const GURL& url, Predictor* predictor);
    382 
    383     // Get an HTML version of our current planned first_navigations_.
    384     void GetFirstResolutionsHtml(std::string* output);
    385 
    386     // Persist the current first_navigations_ for storage in a list.
    387     void GetInitialDnsResolutionList(base::ListValue* startup_list);
    388 
    389     // Discards all initial loading history.
    390     void DiscardInitialNavigationHistory() { first_navigations_.clear(); }
    391 
    392    private:
    393     // List of the first N URL resolutions observed in this run.
    394     FirstNavigations first_navigations_;
    395 
    396     // The number of URLs we'll save for pre-resolving at next startup.
    397     static const size_t kStartupResolutionCount = 10;
    398   };
    399 
    400   // A map that is keyed with the host/port that we've learned were the cause
    401   // of loading additional URLs.  The list of additional targets is held
    402   // in a Referrer instance, which is a value in this map.
    403   typedef std::map<GURL, Referrer> Referrers;
    404 
    405   // Depending on the expected_subresource_use_, we may either make a TCP/IP
    406   // preconnection, or merely pre-resolve the hostname via DNS (or even do
    407   // nothing).  The following are the threasholds for taking those actions.
    408   static const double kPreconnectWorthyExpectedValue;
    409   static const double kDNSPreresolutionWorthyExpectedValue;
    410   // Referred hosts with a subresource_use_rate_ that are less than the
    411   // following threshold will be discarded when we Trim() the list.
    412   static const double kDiscardableExpectedValue;
    413   // During trimming operation to discard hosts for which we don't have likely
    414   // subresources, we multiply the expected_subresource_use_ value by the
    415   // following ratio until that value is less than kDiscardableExpectedValue.
    416   // This number should always be less than 1, an more than 0.
    417   static const double kReferrerTrimRatio;
    418 
    419   // Interval between periodic trimming of our whole referrer list.
    420   // We only do a major trimming about once an hour, and then only when the user
    421   // is actively browsing.
    422   static const int64 kDurationBetweenTrimmingsHours;
    423   // Interval between incremental trimmings (to avoid inducing Jank).
    424   static const int64 kDurationBetweenTrimmingIncrementsSeconds;
    425   // Number of referring URLs processed in an incremental trimming.
    426   static const size_t kUrlsTrimmedPerIncrement;
    427 
    428   // Only for testing. Returns true if hostname has been successfully resolved
    429   // (name found).
    430   bool WasFound(const GURL& url) const {
    431     Results::const_iterator it(results_.find(url));
    432     return (it != results_.end()) &&
    433             it->second.was_found();
    434   }
    435 
    436   // Only for testing. Return how long was the resolution
    437   // or UrlInfo::NullDuration() if it hasn't been resolved yet.
    438   base::TimeDelta GetResolutionDuration(const GURL& url) {
    439     if (results_.find(url) == results_.end())
    440       return UrlInfo::NullDuration();
    441     return results_[url].resolve_duration();
    442   }
    443 
    444   // Only for testing;
    445   size_t peak_pending_lookups() const { return peak_pending_lookups_; }
    446 
    447   // If a proxy advisor is defined, let it know that |url| will be prefetched or
    448   // preconnected to. Can be called on either UI or IO threads and will post to
    449   // the IO thread if necessary, invoking AdviseProxyOnIOThread().
    450   void AdviseProxy(const GURL& url,
    451                    UrlInfo::ResolutionMotivation motivation,
    452                    bool is_preconnect);
    453 
    454   // ------------- Start IO thread methods.
    455 
    456   // Perform actual resolution or preconnection to subresources now.  This is
    457   // an internal worker method that is reached via a post task from
    458   // PredictFrameSubresources().
    459   void PrepareFrameSubresources(const GURL& url,
    460                                 const GURL& first_party_for_cookies);
    461 
    462   // Access method for use by async lookup request to pass resolution result.
    463   void OnLookupFinished(LookupRequest* request, const GURL& url, bool found);
    464 
    465   // Underlying method for both async and synchronous lookup to update state.
    466   void LookupFinished(LookupRequest* request,
    467                       const GURL& url, bool found);
    468 
    469   // Queue hostname for resolution.  If queueing was done, return the pointer
    470   // to the queued instance, otherwise return NULL. If the proxy advisor is
    471   // enabled, and |url| is likely to be proxied, the hostname will not be
    472   // queued as the browser is not expected to fetch it directly.
    473   UrlInfo* AppendToResolutionQueue(const GURL& url,
    474                                    UrlInfo::ResolutionMotivation motivation);
    475 
    476   // Check to see if too much queuing delay has been noted for the given info,
    477   // which indicates that there is "congestion" or growing delay in handling the
    478   // resolution of names.  Rather than letting this congestion potentially grow
    479   // without bounds, we abandon our queued efforts at pre-resolutions in such a
    480   // case.
    481   // To do this, we will recycle |info|, as well as all queued items, back to
    482   // the state they had before they were queued up.  We can't do anything about
    483   // the resolutions we've already sent off for processing on another thread, so
    484   // we just let them complete.  On a slow system, subject to congestion, this
    485   // will greatly reduce the number of resolutions done, but it will assure that
    486   // any resolutions that are done, are in a timely and hence potentially
    487   // helpful manner.
    488   bool CongestionControlPerformed(UrlInfo* info);
    489 
    490   // Take lookup requests from work_queue_ and tell HostResolver to look them up
    491   // asynchronously, provided we don't exceed concurrent resolution limit.
    492   void StartSomeQueuedResolutions();
    493 
    494   // Performs trimming similar to TrimReferrersNow(), except it does it as a
    495   // series of short tasks by posting continuations again an again until done.
    496   void TrimReferrers();
    497 
    498   // Loads urls_being_trimmed_ from keys of current referrers_.
    499   void LoadUrlsForTrimming();
    500 
    501   // Posts a task to do additional incremental trimming of referrers_.
    502   void PostIncrementalTrimTask();
    503 
    504   // Calls Trim() on some or all of urls_being_trimmed_.
    505   // If it does not process all the URLs in that vector, it posts a task to
    506   // continue with them shortly (i.e., it yeilds and continues).
    507   void IncrementalTrimReferrers(bool trim_all_now);
    508 
    509   // If a proxy advisor is defined, let it know that |url| will be prefetched or
    510   // preconnected to.
    511   void AdviseProxyOnIOThread(const GURL& url,
    512                              UrlInfo::ResolutionMotivation motivation,
    513                              bool is_preconnect);
    514 
    515   // Applies the HSTS redirect for |url|, if any.
    516   GURL GetHSTSRedirectOnIOThread(const GURL& url);
    517 
    518   // ------------- End IO thread methods.
    519 
    520   scoped_ptr<InitialObserver> initial_observer_;
    521 
    522   // Reference to URLRequestContextGetter from the Profile which owns the
    523   // predictor. Used by Preconnect.
    524   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
    525 
    526   // Status of speculative DNS resolution and speculative TCP/IP connection
    527   // feature.
    528   bool predictor_enabled_;
    529 
    530   // work_queue_ holds a list of names we need to look up.
    531   HostNameQueue work_queue_;
    532 
    533   // results_ contains information for existing/prior prefetches.
    534   Results results_;
    535 
    536   std::set<LookupRequest*> pending_lookups_;
    537 
    538   // For testing, to verify that we don't exceed the limit.
    539   size_t peak_pending_lookups_;
    540 
    541   // When true, we don't make new lookup requests.
    542   bool shutdown_;
    543 
    544   // The number of concurrent speculative lookups currently allowed to be sent
    545   // to the resolver.  Any additional lookups will be queued to avoid exceeding
    546   // this value.  The queue is a priority queue that will accelerate
    547   // sub-resource speculation, and retard resolutions suggested by page scans.
    548   const size_t max_concurrent_dns_lookups_;
    549 
    550   // The maximum queueing delay that is acceptable before we enter congestion
    551   // reduction mode, and discard all queued (but not yet assigned) resolutions.
    552   const base::TimeDelta max_dns_queue_delay_;
    553 
    554   // The host resolver we warm DNS entries for.
    555   net::HostResolver* host_resolver_;
    556 
    557   // The TransportSecurityState instance we query HSTS redirects from.
    558   net::TransportSecurityState* transport_security_state_;
    559 
    560   // The SSLConfigService we query SNI support from (used in querying HSTS
    561   // redirects).
    562   net::SSLConfigService* ssl_config_service_;
    563 
    564   // Are we currently using preconnection, rather than just DNS resolution, for
    565   // subresources and omni-box search URLs.
    566   bool preconnect_enabled_;
    567 
    568   // Most recent suggestion from Omnibox provided via AnticipateOmniboxUrl().
    569   std::string last_omnibox_host_;
    570 
    571   // The time when the last preresolve was done for last_omnibox_host_.
    572   base::TimeTicks last_omnibox_preresolve_;
    573 
    574   // The number of consecutive requests to AnticipateOmniboxUrl() that suggested
    575   // preconnecting (because it was to a search service).
    576   int consecutive_omnibox_preconnect_count_;
    577 
    578   // The time when the last preconnection was requested to a search service.
    579   base::TimeTicks last_omnibox_preconnect_;
    580 
    581   class PreconnectUsage;
    582   scoped_ptr<PreconnectUsage> preconnect_usage_;
    583 
    584   // For each URL that we might navigate to (that we've "learned about")
    585   // we have a Referrer list. Each Referrer list has all hostnames we might
    586   // need to pre-resolve or pre-connect to when there is a navigation to the
    587   // orginial hostname.
    588   Referrers referrers_;
    589 
    590   // List of URLs in referrers_ currently being trimmed (scaled down to
    591   // eventually be aged out of use).
    592   std::vector<GURL> urls_being_trimmed_;
    593 
    594   // A time after which we need to do more trimming of referrers.
    595   base::TimeTicks next_trim_time_;
    596 
    597   scoped_ptr<base::WeakPtrFactory<Predictor> > weak_factory_;
    598 
    599   scoped_ptr<ProxyAdvisor> proxy_advisor_;
    600 
    601   // An observer for testing.
    602   PredictorObserver* observer_;
    603 
    604   DISALLOW_COPY_AND_ASSIGN(Predictor);
    605 };
    606 
    607 // This version of the predictor is used for testing.
    608 class SimplePredictor : public Predictor {
    609  public:
    610   explicit SimplePredictor(bool preconnect_enabled)
    611       : Predictor(preconnect_enabled) {}
    612   virtual ~SimplePredictor() {}
    613   virtual void InitNetworkPredictor(
    614       PrefService* user_prefs,
    615       PrefService* local_state,
    616       IOThread* io_thread,
    617       net::URLRequestContextGetter* getter) OVERRIDE;
    618   virtual void ShutdownOnUIThread() OVERRIDE;
    619 };
    620 
    621 }  // namespace chrome_browser_net
    622 
    623 #endif  // CHROME_BROWSER_NET_PREDICTOR_H_
    624