Home | History | Annotate | Download | only in prerender
      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 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
      6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
      7 
      8 #include <list>
      9 #include <map>
     10 #include <string>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "base/containers/hash_tables.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/memory/scoped_vector.h"
     18 #include "base/memory/weak_ptr.h"
     19 #include "base/threading/non_thread_safe.h"
     20 #include "base/time/time.h"
     21 #include "base/timer/timer.h"
     22 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
     23 #include "chrome/browser/predictors/logged_in_predictor_table.h"
     24 #include "chrome/browser/prerender/prerender_config.h"
     25 #include "chrome/browser/prerender/prerender_contents.h"
     26 #include "chrome/browser/prerender/prerender_final_status.h"
     27 #include "chrome/browser/prerender/prerender_origin.h"
     28 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     29 #include "content/public/browser/notification_observer.h"
     30 #include "content/public/browser/notification_registrar.h"
     31 #include "net/cookies/cookie_monster.h"
     32 #include "url/gurl.h"
     33 
     34 class Profile;
     35 struct ChromeCookieDetails;
     36 
     37 namespace base {
     38 class DictionaryValue;
     39 }
     40 
     41 namespace content {
     42 class WebContents;
     43 }
     44 
     45 namespace gfx {
     46 class Size;
     47 }
     48 
     49 namespace net {
     50 class URLRequestContextGetter;
     51 }
     52 
     53 #if defined(COMPILER_GCC)
     54 
     55 namespace BASE_HASH_NAMESPACE {
     56 template <>
     57 struct hash<content::WebContents*> {
     58   std::size_t operator()(content::WebContents* value) const {
     59     return reinterpret_cast<std::size_t>(value);
     60   }
     61 };
     62 
     63 }  // namespace BASE_HASH_NAMESPACE
     64 
     65 #endif
     66 
     67 namespace prerender {
     68 
     69 class PrerenderCondition;
     70 class PrerenderHandle;
     71 class PrerenderHistograms;
     72 class PrerenderHistory;
     73 class PrerenderLocalPredictor;
     74 class PrerenderTracker;
     75 
     76 // PrerenderManager is responsible for initiating and keeping prerendered
     77 // views of web pages. All methods must be called on the UI thread unless
     78 // indicated otherwise.
     79 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
     80                          public base::NonThreadSafe,
     81                          public content::NotificationObserver,
     82                          public BrowserContextKeyedService,
     83                          public MediaCaptureDevicesDispatcher::Observer {
     84  public:
     85   // NOTE: New values need to be appended, since they are used in histograms.
     86   enum PrerenderManagerMode {
     87     PRERENDER_MODE_DISABLED = 0,
     88     PRERENDER_MODE_ENABLED = 1,
     89     PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2,
     90     PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3,
     91     // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4,
     92     PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5,
     93     PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6,
     94     PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7,
     95     PRERENDER_MODE_MAX
     96   };
     97 
     98   // One or more of these flags must be passed to ClearData() to specify just
     99   // what data to clear.  See function declaration for more information.
    100   enum ClearFlags {
    101     CLEAR_PRERENDER_CONTENTS = 0x1 << 0,
    102     CLEAR_PRERENDER_HISTORY = 0x1 << 1,
    103     CLEAR_MAX = 0x1 << 2
    104   };
    105 
    106   typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap;
    107 
    108   // ID indicating that no experiment is active.
    109   static const uint8 kNoExperiment = 0;
    110 
    111   // Owned by a Profile object for the lifetime of the profile.
    112   PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
    113 
    114   virtual ~PrerenderManager();
    115 
    116   // From BrowserContextKeyedService:
    117   virtual void Shutdown() OVERRIDE;
    118 
    119   // Entry points for adding prerenders.
    120 
    121   // Adds a prerender for |url| if valid. |process_id| and |route_id| identify
    122   // the RenderView that the prerender request came from. If |size| is empty, a
    123   // default from the PrerenderConfig is used. Returns a caller-owned
    124   // PrerenderHandle* if the URL was added, NULL if it was not. If the launching
    125   // RenderView is itself prerendering, the prerender is added as a pending
    126   // prerender.
    127   PrerenderHandle* AddPrerenderFromLinkRelPrerender(
    128       int process_id,
    129       int route_id,
    130       const GURL& url,
    131       const content::Referrer& referrer,
    132       const gfx::Size& size);
    133 
    134   // Adds a prerender for |url| if valid. As the prerender request is coming
    135   // from a source without a RenderViewHost (i.e., the omnibox) we don't have a
    136   // child or route id, or a referrer. This method uses sensible values for
    137   // those. The |session_storage_namespace| matches the namespace of the active
    138   // tab at the time the prerender is generated from the omnibox. Returns a
    139   // caller-owned PrerenderHandle*, or NULL.
    140   PrerenderHandle* AddPrerenderFromOmnibox(
    141       const GURL& url,
    142       content::SessionStorageNamespace* session_storage_namespace,
    143       const gfx::Size& size);
    144 
    145   PrerenderHandle* AddPrerenderFromLocalPredictor(
    146       const GURL& url,
    147       content::SessionStorageNamespace* session_storage_namespace,
    148       const gfx::Size& size);
    149 
    150   // If |process_id| and |view_id| refer to a running prerender, destroy
    151   // it with |final_status|.
    152   virtual void DestroyPrerenderForRenderView(int process_id,
    153                                              int view_id,
    154                                              FinalStatus final_status);
    155 
    156   // Cancels all active prerenders.
    157   void CancelAllPrerenders();
    158 
    159   // If |url| matches a valid prerendered page, try to swap it into
    160   // |web_contents| and merge browsing histories. Returns |true| if a
    161   // prerendered page is swapped in, |false| otherwise.
    162   bool MaybeUsePrerenderedPage(content::WebContents* web_contents,
    163                                const GURL& url);
    164 
    165   // Moves a PrerenderContents to the pending delete list from the list of
    166   // active prerenders when prerendering should be cancelled.
    167   virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
    168                                         FinalStatus final_status);
    169 
    170   // Records the perceived page load time for a page - effectively the time from
    171   // when the user navigates to a page to when it finishes loading. The actual
    172   // load may have started prior to navigation due to prerender hints.
    173   // This must be called on the UI thread.
    174   // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value
    175   // outside that range indicating that it doesn't apply.
    176   static void RecordPerceivedPageLoadTime(
    177       base::TimeDelta perceived_page_load_time,
    178       double fraction_plt_elapsed_at_swap_in,
    179       content::WebContents* web_contents,
    180       const GURL& url);
    181 
    182   // Records the percentage of pixels of the final page in place at swap-in.
    183   void RecordFractionPixelsFinalAtSwapin(
    184       content::WebContents* web_contents,
    185       double fraction);
    186 
    187   // Set whether prerendering is currently enabled for this manager.
    188   // Must be called on the UI thread.
    189   // If |enabled| is false, existing prerendered pages will still persist until
    190   // they time out, but new ones will not be generated.
    191   void set_enabled(bool enabled);
    192 
    193   // Controls if we launch or squash prefetch requests as they arrive from
    194   // renderers.
    195   static bool IsPrefetchEnabled();
    196   static void SetIsPrefetchEnabled(bool enabled);
    197 
    198   static PrerenderManagerMode GetMode();
    199   static void SetMode(PrerenderManagerMode mode);
    200   static const char* GetModeString();
    201   static bool IsPrerenderingPossible();
    202   static bool ActuallyPrerendering();
    203   static bool IsControlGroup(uint8 experiment_id);
    204   static bool IsNoUseGroup();
    205 
    206   // Query the list of current prerender pages to see if the given web contents
    207   // is prerendering a page. The optional parameter |origin| is an output
    208   // parameter which, if a prerender is found, is set to the Origin of the
    209   // prerender |web_contents|.
    210   bool IsWebContentsPrerendering(const content::WebContents* web_contents,
    211                                  Origin* origin) const;
    212 
    213   // Returns the PrerenderContents object for the given web_contents if it's
    214   // used for an active prerender page, otherwise returns NULL.
    215   PrerenderContents* GetPrerenderContents(
    216       const content::WebContents* web_contents) const;
    217 
    218   // Returns a list of all WebContents being prerendered.
    219   const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
    220 
    221   // Maintaining and querying the set of WebContents belonging to this
    222   // PrerenderManager that are currently showing prerendered pages.
    223   void MarkWebContentsAsPrerendered(content::WebContents* web_contents,
    224                                     Origin origin);
    225   void MarkWebContentsAsWouldBePrerendered(content::WebContents* web_contents,
    226                                            Origin origin);
    227   void MarkWebContentsAsNotPrerendered(content::WebContents* web_contents);
    228 
    229   // Returns true if |web_contents| was originally a prerender that has since
    230   // been swapped in. The optional parameter |origin| is an output parameter
    231   // which, if a prerender is found, is set to the Origin of the prerender of
    232   // |web_contents|.
    233   bool IsWebContentsPrerendered(content::WebContents* web_contents,
    234                                 Origin* origin) const;
    235   bool WouldWebContentsBePrerendered(content::WebContents* web_contents,
    236                                      Origin* origin) const;
    237 
    238   // Checks whether |url| has been recently navigated to.
    239   bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
    240 
    241   // Returns true iff the method given is valid for prerendering.
    242   static bool IsValidHttpMethod(const std::string& method);
    243 
    244   // Returns true iff the scheme of the URL given is valid for prerendering.
    245   static bool DoesURLHaveValidScheme(const GURL& url);
    246 
    247   // Returns true iff the scheme of the subresource URL given is valid for
    248   // prerendering.
    249   static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
    250 
    251   // Returns a Value object containing the active pages being prerendered, and
    252   // a history of pages which were prerendered. The caller is responsible for
    253   // deleting the return value.
    254   base::DictionaryValue* GetAsValue() const;
    255 
    256   // Clears the data indicated by which bits of clear_flags are set.
    257   //
    258   // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are
    259   // cancelled and then deleted, and any WebContents queued for destruction are
    260   // destroyed as well.
    261   //
    262   // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is
    263   // cleared, including any entries newly created by destroying them in
    264   // response to the CLEAR_PRERENDER_CONTENTS flag.
    265   //
    266   // Intended to be used when clearing the cache or history.
    267   void ClearData(int clear_flags);
    268 
    269   // Record a final status of a prerendered page in a histogram.
    270   // This variation allows specifying whether prerendering had been started
    271   // (necessary to flag MatchComplete dummies).
    272   void RecordFinalStatusWithMatchCompleteStatus(
    273       Origin origin,
    274       uint8 experiment_id,
    275       PrerenderContents::MatchCompleteStatus mc_status,
    276       FinalStatus final_status) const;
    277 
    278   // content::NotificationObserver
    279   virtual void Observe(int type,
    280                        const content::NotificationSource& source,
    281                        const content::NotificationDetails& details) OVERRIDE;
    282 
    283   // MediaCaptureDevicesDispatcher::Observer
    284   virtual void OnCreatingAudioStream(int render_process_id,
    285                                      int render_view_id) OVERRIDE;
    286 
    287   const Config& config() const { return config_; }
    288   Config& mutable_config() { return config_; }
    289 
    290   PrerenderTracker* prerender_tracker() { return prerender_tracker_; }
    291 
    292   // Adds a condition. This is owned by the PrerenderManager.
    293   void AddCondition(const PrerenderCondition* condition);
    294 
    295   // Records that some visible tab navigated (or was redirected) to the
    296   // provided URL.
    297   void RecordNavigation(const GURL& url);
    298 
    299   // Updates the LoggedInPredictor state to reflect that a login has likely
    300   // on the URL provided.
    301   void RecordLikelyLoginOnURL(const GURL& url);
    302 
    303   // Checks if the LoggedInPredictor shows that the user is likely logged on
    304   // to the site for the URL provided.
    305   void CheckIfLikelyLoggedInOnURL(const GURL& url,
    306                                   bool* lookup_result,
    307                                   bool* database_was_present,
    308                                   const base::Closure& result_cb);
    309 
    310   Profile* profile() const { return profile_; }
    311 
    312   // Classes which will be tested in prerender unit browser tests should use
    313   // these methods to get times for comparison, so that the test framework can
    314   // mock advancing/retarding time.
    315   virtual base::Time GetCurrentTime() const;
    316   virtual base::TimeTicks GetCurrentTimeTicks() const;
    317 
    318   scoped_refptr<predictors::LoggedInPredictorTable>
    319   logged_in_predictor_table() {
    320     return logged_in_predictor_table_;
    321   }
    322 
    323   PrerenderLocalPredictor* local_predictor() {
    324     return local_predictor_.get();
    325   }
    326 
    327  protected:
    328   class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
    329    public:
    330     struct OrderByExpiryTime;
    331 
    332     PrerenderData(PrerenderManager* manager,
    333                   PrerenderContents* contents,
    334                   base::TimeTicks expiry_time);
    335 
    336     ~PrerenderData();
    337 
    338     // Turn this PrerenderData into a Match Complete replacement for itself,
    339     // placing the current prerender contents into |to_delete_prerenders_|.
    340     void MakeIntoMatchCompleteReplacement();
    341 
    342     // A new PrerenderHandle has been created for this PrerenderData.
    343     void OnHandleCreated(PrerenderHandle* prerender_handle);
    344 
    345     // The launcher associated with a handle is navigating away from the context
    346     // that launched this prerender. If the prerender is active, it may stay
    347     // alive briefly though, in case we we going through a redirect chain that
    348     // will eventually land at it.
    349     void OnHandleNavigatedAway(PrerenderHandle* prerender_handle);
    350 
    351     // The launcher associated with a handle has taken explicit action to cancel
    352     // this prerender. We may well destroy the prerender in this case if no
    353     // other handles continue to track it.
    354     void OnHandleCanceled(PrerenderHandle* prerender_handle);
    355 
    356     PrerenderContents* contents() { return contents_.get(); }
    357 
    358     PrerenderContents* ReleaseContents();
    359 
    360     int handle_count() const { return handle_count_; }
    361 
    362     base::TimeTicks expiry_time() const { return expiry_time_; }
    363     void set_expiry_time(base::TimeTicks expiry_time) {
    364       expiry_time_ = expiry_time;
    365     }
    366 
    367    private:
    368     PrerenderManager* manager_;
    369     scoped_ptr<PrerenderContents> contents_;
    370 
    371     // The number of distinct PrerenderHandles created for |this|, including
    372     // ones that have called PrerenderData::OnHandleNavigatedAway(), but not
    373     // counting the ones that have called PrerenderData::OnHandleCanceled(). For
    374     // pending prerenders, this will always be 1, since the PrerenderManager
    375     // only merges handles of running prerenders.
    376     int handle_count_;
    377 
    378     // After this time, this prerender is no longer fresh, and should be
    379     // removed.
    380     base::TimeTicks expiry_time_;
    381 
    382     DISALLOW_COPY_AND_ASSIGN(PrerenderData);
    383   };
    384 
    385   void SetPrerenderContentsFactory(
    386       PrerenderContents::Factory* prerender_contents_factory);
    387 
    388   // Adds prerenders from the pending Prerenders, called by
    389   // PrerenderContents::StartPendingPrerenders.
    390   void StartPendingPrerenders(
    391       int process_id,
    392       ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders,
    393       content::SessionStorageNamespace* session_storage_namespace);
    394 
    395   // Called by a PrerenderData to signal that the launcher has navigated away
    396   // from the context that launched the prerender. A user may have clicked
    397   // a link in a page containing a <link rel=prerender> element, or the user
    398   // might have committed an omnibox navigation. This is used to possibly
    399   // shorten the TTL of the prerendered page.
    400   void SourceNavigatedAway(PrerenderData* prerender_data);
    401 
    402  private:
    403   friend class PrerenderBrowserTest;
    404   friend class PrerenderContents;
    405   friend class PrerenderHandle;
    406   friend class UnitTestPrerenderManager;
    407 
    408   class OnCloseWebContentsDeleter;
    409   struct NavigationRecord;
    410 
    411   // For each WebContents that is swapped in, we store a
    412   // PrerenderedWebContentsData so that we can track the origin of the
    413   // prerender.
    414   struct PrerenderedWebContentsData {
    415     explicit PrerenderedWebContentsData(Origin origin);
    416 
    417     Origin origin;
    418   };
    419 
    420   // In the control group experimental group for each WebContents "not swapped
    421   // in" we create a WouldBePrerenderedWebContentsData to the origin of the
    422   // "prerender" we did not launch. We also track a state machine to ensure
    423   // the histogram reporting tracks what histograms would have done.
    424   struct WouldBePrerenderedWebContentsData {
    425     // When the WebContents gets a provisional load, we'd like to remove the
    426     // WebContents from  the map since the new navigation would not have swapped
    427     // in a prerender. But the first provisional load after the control
    428     // prerender is not "swapped in" is actually to the prerendered location! So
    429     // we don't remove the item from the map on the first provisional load, but
    430     // we do for subsequent loads.
    431     enum State {
    432       WAITING_FOR_PROVISIONAL_LOAD,
    433       SEEN_PROVISIONAL_LOAD,
    434     };
    435 
    436     explicit WouldBePrerenderedWebContentsData(Origin origin);
    437 
    438     Origin origin;
    439     State state;
    440   };
    441 
    442   // Time interval before a new prerender is allowed.
    443   static const int kMinTimeBetweenPrerendersMs = 500;
    444 
    445   // Time window for which we record old navigations, in milliseconds.
    446   static const int kNavigationRecordWindowMs = 5000;
    447 
    448   void OnCancelPrerenderHandle(PrerenderData* prerender_data);
    449 
    450   // Adds a prerender for |url| from |referrer| initiated from the process
    451   // |child_id|. The |origin| specifies how the prerender was added. If |size|
    452   // is empty, then PrerenderContents::StartPrerendering will instead use a
    453   // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the
    454   // caller, or NULL.
    455   PrerenderHandle* AddPrerender(
    456       Origin origin,
    457       int child_id,
    458       const GURL& url,
    459       const content::Referrer& referrer,
    460       const gfx::Size& size,
    461       content::SessionStorageNamespace* session_storage_namespace);
    462 
    463   void StartSchedulingPeriodicCleanups();
    464   void StopSchedulingPeriodicCleanups();
    465 
    466   void EvictOldestPrerendersIfNecessary();
    467 
    468   // Deletes stale and cancelled prerendered PrerenderContents, as well as
    469   // WebContents that have been replaced by prerendered WebContents.
    470   // Also identifies and kills PrerenderContents that use too much
    471   // resources.
    472   void PeriodicCleanup();
    473 
    474   // Posts a task to call PeriodicCleanup.  Results in quicker destruction of
    475   // objects.  If |this| is deleted before the task is run, the task will
    476   // automatically be cancelled.
    477   void PostCleanupTask();
    478 
    479   base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
    480   base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
    481 
    482   void DeleteOldEntries();
    483   virtual PrerenderContents* CreatePrerenderContents(
    484       const GURL& url,
    485       const content::Referrer& referrer,
    486       Origin origin,
    487       uint8 experiment_id);
    488 
    489   // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
    490   // after every mutation of active_prerenders_ that can possibly make it
    491   // unsorted (e.g. an insert, or changing an expiry time).
    492   void SortActivePrerenders();
    493 
    494   // Finds the active PrerenderData object for a running prerender matching
    495   // |url| and |session_storage_namespace|.
    496   PrerenderData* FindPrerenderData(
    497       const GURL& url,
    498       const content::SessionStorageNamespace* session_storage_namespace);
    499 
    500   // If |child_id| and |route_id| correspond to a RenderView that is an active
    501   // prerender, returns the PrerenderData object for that prerender. Otherwise,
    502   // returns NULL.
    503   PrerenderData* FindPrerenderDataForChildAndRoute(int child_id, int route_id);
    504 
    505   // Given the |prerender_contents|, find the iterator in active_prerenders_
    506   // correponding to the given prerender.
    507   ScopedVector<PrerenderData>::iterator
    508       FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
    509 
    510   bool DoesRateLimitAllowPrerender(Origin origin) const;
    511 
    512   // Deletes old WebContents that have been replaced by prerendered ones.  This
    513   // is needed because they're replaced in a callback from the old WebContents,
    514   // so cannot immediately be deleted.
    515   void DeleteOldWebContents();
    516 
    517   // Cleans up old NavigationRecord's.
    518   void CleanUpOldNavigations();
    519 
    520   // Arrange for the given WebContents to be deleted asap. If deleter is not
    521   // NULL, deletes that as well.
    522   void ScheduleDeleteOldWebContents(content::WebContents* tab,
    523                                     OnCloseWebContentsDeleter* deleter);
    524 
    525   // Adds to the history list.
    526   void AddToHistory(PrerenderContents* contents);
    527 
    528   // Returns a new Value representing the pages currently being prerendered. The
    529   // caller is responsible for delete'ing the return value.
    530   base::Value* GetActivePrerendersAsValue() const;
    531 
    532   // Destroys all pending prerenders using FinalStatus.  Also deletes them as
    533   // well as any swapped out WebContents queued for destruction.
    534   // Used both on destruction, and when clearing the browsing history.
    535   void DestroyAllContents(FinalStatus final_status);
    536 
    537   // Helper function to destroy a PrerenderContents with the specified
    538   // final_status, while at the same time recording that for the MatchComplete
    539   // case, that this prerender would have been used.
    540   void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents,
    541                                          FinalStatus final_status);
    542 
    543   // Record a final status of a prerendered page in a histogram.
    544   // This is a helper function which will ultimately call
    545   // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
    546   void RecordFinalStatus(Origin origin,
    547                          uint8 experiment_id,
    548                          FinalStatus final_status) const;
    549 
    550   // Returns whether prerendering is currently enabled for this manager.
    551   // Must be called on the UI thread.
    552   bool IsEnabled() const;
    553 
    554   void CookieChanged(ChromeCookieDetails* details);
    555   void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key,
    556                                                bool cookies_exist);
    557   void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map);
    558 
    559   // The configuration.
    560   Config config_;
    561 
    562   // Specifies whether prerendering is currently enabled for this
    563   // manager. The value can change dynamically during the lifetime
    564   // of the PrerenderManager.
    565   bool enabled_;
    566 
    567   static bool is_prefetch_enabled_;
    568 
    569   // The profile that owns this PrerenderManager.
    570   Profile* profile_;
    571 
    572   PrerenderTracker* prerender_tracker_;
    573 
    574   // All running prerenders. Sorted by expiry time, in ascending order.
    575   ScopedVector<PrerenderData> active_prerenders_;
    576 
    577   // Prerenders awaiting deletion.
    578   ScopedVector<PrerenderData> to_delete_prerenders_;
    579 
    580   // List of recent navigations in this profile, sorted by ascending
    581   // navigate_time_.
    582   std::list<NavigationRecord> navigations_;
    583 
    584   // This map is from all WebContents which are currently displaying a
    585   // prerendered page which has already been swapped in to a
    586   // PrerenderedWebContentsData for tracking full lifetime information
    587   // on prerenders.
    588   base::hash_map<content::WebContents*, PrerenderedWebContentsData>
    589       prerendered_web_contents_data_;
    590 
    591   // WebContents that would have been swapped out for a prerendered WebContents
    592   // if the user was not part of the control group for measurement. When the
    593   // WebContents gets a provisional load, the WebContents is removed from
    594   // the map since the new navigation would not have swapped in a prerender.
    595   // However, one complication exists because the first provisional load after
    596   // the WebContents is marked as "Would Have Been Prerendered" is actually to
    597   // the prerendered location. So, we need to keep a state around that does
    598   // not clear the item from the map on the first provisional load, but does
    599   // for subsequent loads.
    600   base::hash_map<content::WebContents*, WouldBePrerenderedWebContentsData>
    601       would_be_prerendered_map_;
    602 
    603   scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
    604 
    605   static PrerenderManagerMode mode_;
    606 
    607   // A count of how many prerenders we do per session. Initialized to 0 then
    608   // incremented and emitted to a histogram on each successful prerender.
    609   static int prerenders_per_session_count_;
    610 
    611   // RepeatingTimer to perform periodic cleanups of pending prerendered
    612   // pages.
    613   base::RepeatingTimer<PrerenderManager> repeating_timer_;
    614 
    615   // Track time of last prerender to limit prerender spam.
    616   base::TimeTicks last_prerender_start_time_;
    617 
    618   std::list<content::WebContents*> old_web_contents_list_;
    619 
    620   ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
    621 
    622   scoped_ptr<PrerenderHistory> prerender_history_;
    623 
    624   std::list<const PrerenderCondition*> prerender_conditions_;
    625 
    626   scoped_ptr<PrerenderHistograms> histograms_;
    627 
    628   scoped_ptr<PrerenderLocalPredictor> local_predictor_;
    629 
    630   scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_;
    631 
    632   // Here, we keep the logged in predictor state, but potentially a superset
    633   // of its actual (database-backed) state, since we do not incorporate
    634   // browser data deletion. We do not use this for actual lookups, but only
    635   // to query cookie data for domains we know there was a login before.
    636   // This is required to avoid a large number of cookie lookups on bulk
    637   // deletion of cookies.
    638   scoped_ptr<LoggedInStateMap> logged_in_state_;
    639 
    640   content::NotificationRegistrar notification_registrar_;
    641 
    642   DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
    643 };
    644 
    645 PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
    646     int render_process_id);
    647 
    648 }  // namespace prerender
    649 
    650 #endif  // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
    651