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/gtest_prod_util.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/scoped_vector.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "base/task/cancelable_task_tracker.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/history/history_service.h"
     23 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
     24 #include "chrome/browser/predictors/logged_in_predictor_table.h"
     25 #include "chrome/browser/prerender/prerender_config.h"
     26 #include "chrome/browser/prerender/prerender_contents.h"
     27 #include "chrome/browser/prerender/prerender_events.h"
     28 #include "chrome/browser/prerender/prerender_final_status.h"
     29 #include "chrome/browser/prerender/prerender_histograms.h"
     30 #include "chrome/browser/prerender/prerender_origin.h"
     31 #include "chrome/browser/prerender/prerender_tracker.h"
     32 #include "components/keyed_service/core/keyed_service.h"
     33 #include "content/public/browser/notification_observer.h"
     34 #include "content/public/browser/notification_registrar.h"
     35 #include "content/public/browser/render_process_host_observer.h"
     36 #include "content/public/browser/session_storage_namespace.h"
     37 #include "content/public/browser/web_contents_observer.h"
     38 #include "net/cookies/canonical_cookie.h"
     39 #include "net/cookies/cookie_monster.h"
     40 #include "url/gurl.h"
     41 
     42 class Profile;
     43 class InstantSearchPrerendererTest;
     44 struct ChromeCookieDetails;
     45 
     46 namespace base {
     47 class DictionaryValue;
     48 }
     49 
     50 namespace chrome {
     51 struct NavigateParams;
     52 }
     53 
     54 namespace content {
     55 class WebContents;
     56 }
     57 
     58 namespace gfx {
     59 class Size;
     60 }
     61 
     62 namespace net {
     63 class URLRequestContextGetter;
     64 }
     65 
     66 namespace prerender {
     67 
     68 class PrerenderCondition;
     69 class PrerenderHandle;
     70 class PrerenderHistory;
     71 class PrerenderLocalPredictor;
     72 
     73 // PrerenderManager is responsible for initiating and keeping prerendered
     74 // views of web pages. All methods must be called on the UI thread unless
     75 // indicated otherwise.
     76 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
     77                          public base::NonThreadSafe,
     78                          public content::NotificationObserver,
     79                          public content::RenderProcessHostObserver,
     80                          public KeyedService,
     81                          public MediaCaptureDevicesDispatcher::Observer {
     82  public:
     83   // NOTE: New values need to be appended, since they are used in histograms.
     84   enum PrerenderManagerMode {
     85     PRERENDER_MODE_DISABLED = 0,
     86     PRERENDER_MODE_ENABLED = 1,
     87     PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2,
     88     PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3,
     89     // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4,
     90     PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5,
     91     PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6,
     92     PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7,
     93     PRERENDER_MODE_MAX
     94   };
     95 
     96   // One or more of these flags must be passed to ClearData() to specify just
     97   // what data to clear.  See function declaration for more information.
     98   enum ClearFlags {
     99     CLEAR_PRERENDER_CONTENTS = 0x1 << 0,
    100     CLEAR_PRERENDER_HISTORY = 0x1 << 1,
    101     CLEAR_MAX = 0x1 << 2
    102   };
    103 
    104   typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap;
    105 
    106   // ID indicating that no experiment is active.
    107   static const uint8 kNoExperiment = 0;
    108 
    109   // Owned by a Profile object for the lifetime of the profile.
    110   PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
    111 
    112   virtual ~PrerenderManager();
    113 
    114   // From KeyedService:
    115   virtual void Shutdown() OVERRIDE;
    116 
    117   // Entry points for adding prerenders.
    118 
    119   // Adds a prerender for |url| if valid. |process_id| and |route_id| identify
    120   // the RenderView that the prerender request came from. If |size| is empty, a
    121   // default from the PrerenderConfig is used. Returns a caller-owned
    122   // PrerenderHandle* if the URL was added, NULL if it was not. If the launching
    123   // RenderView is itself prerendering, the prerender is added as a pending
    124   // prerender.
    125   PrerenderHandle* AddPrerenderFromLinkRelPrerender(
    126       int process_id,
    127       int route_id,
    128       const GURL& url,
    129       uint32 rel_types,
    130       const content::Referrer& referrer,
    131       const gfx::Size& size);
    132 
    133   // Adds a prerender for |url| if valid. As the prerender request is coming
    134   // from a source without a RenderViewHost (i.e., the omnibox) we don't have a
    135   // child or route id, or a referrer. This method uses sensible values for
    136   // those. The |session_storage_namespace| matches the namespace of the active
    137   // tab at the time the prerender is generated from the omnibox. Returns a
    138   // caller-owned PrerenderHandle*, or NULL.
    139   PrerenderHandle* AddPrerenderFromOmnibox(
    140       const GURL& url,
    141       content::SessionStorageNamespace* session_storage_namespace,
    142       const gfx::Size& size);
    143 
    144   PrerenderHandle* AddPrerenderFromLocalPredictor(
    145       const GURL& url,
    146       content::SessionStorageNamespace* session_storage_namespace,
    147       const gfx::Size& size);
    148 
    149   PrerenderHandle* AddPrerenderFromExternalRequest(
    150       const GURL& url,
    151       const content::Referrer& referrer,
    152       content::SessionStorageNamespace* session_storage_namespace,
    153       const gfx::Size& size);
    154 
    155   // Adds a prerender for Instant Search |url| if valid. The
    156   // |session_storage_namespace| matches the namespace of the active tab at the
    157   // time the prerender is generated. Returns a caller-owned PrerenderHandle* or
    158   // NULL.
    159   PrerenderHandle* AddPrerenderForInstant(
    160       const GURL& url,
    161       content::SessionStorageNamespace* session_storage_namespace,
    162       const gfx::Size& size);
    163 
    164   // Cancels all active prerenders.
    165   void CancelAllPrerenders();
    166 
    167   // If |url| matches a valid prerendered page and |params| are compatible, try
    168   // to swap it and merge browsing histories. Returns |true| and updates
    169   // |params->target_contents| if a prerendered page is swapped in, |false|
    170   // otherwise.
    171   bool MaybeUsePrerenderedPage(const GURL& url,
    172                                chrome::NavigateParams* params);
    173 
    174   // Moves a PrerenderContents to the pending delete list from the list of
    175   // active prerenders when prerendering should be cancelled.
    176   virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
    177                                         FinalStatus final_status);
    178 
    179   // Records the page load time for a prerender that wasn't swapped in.
    180   void RecordPageLoadTimeNotSwappedIn(Origin origin,
    181                                       base::TimeDelta page_load_time,
    182                                       const GURL& url);
    183 
    184   // Records the perceived page load time for a page - effectively the time from
    185   // when the user navigates to a page to when it finishes loading. The actual
    186   // load may have started prior to navigation due to prerender hints.
    187   // This must be called on the UI thread.
    188   // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value
    189   // outside that range indicating that it doesn't apply.
    190   void RecordPerceivedPageLoadTime(
    191       Origin origin,
    192       NavigationType navigation_type,
    193       base::TimeDelta perceived_page_load_time,
    194       double fraction_plt_elapsed_at_swap_in,
    195       const GURL& url);
    196 
    197   // Set whether prerendering is currently enabled for this manager.
    198   // Must be called on the UI thread.
    199   // If |enabled| is false, existing prerendered pages will still persist until
    200   // they time out, but new ones will not be generated.
    201   void set_enabled(bool enabled);
    202 
    203   static PrerenderManagerMode GetMode();
    204   static void SetMode(PrerenderManagerMode mode);
    205   static const char* GetModeString();
    206   static bool IsPrerenderingPossible();
    207   static bool ActuallyPrerendering();
    208   static bool IsControlGroup(uint8 experiment_id);
    209   static bool IsNoUseGroup();
    210 
    211   // Query the list of current prerender pages to see if the given web contents
    212   // is prerendering a page. The optional parameter |origin| is an output
    213   // parameter which, if a prerender is found, is set to the Origin of the
    214   // prerender |web_contents|.
    215   bool IsWebContentsPrerendering(const content::WebContents* web_contents,
    216                                  Origin* origin) const;
    217 
    218   // Whether the PrerenderManager has an active prerender with the given url and
    219   // SessionStorageNamespace associated with the given WebContens.
    220   bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const;
    221 
    222   // Returns the PrerenderContents object for the given web_contents, otherwise
    223   // returns NULL. Note that the PrerenderContents may have been Destroy()ed,
    224   // but not yet deleted.
    225   PrerenderContents* GetPrerenderContents(
    226       const content::WebContents* web_contents) const;
    227 
    228   // Returns the PrerenderContents object for a given child_id, route_id pair,
    229   // otherwise returns NULL. Note that the PrerenderContents may have been
    230   // Destroy()ed, but not yet deleted.
    231   virtual PrerenderContents* GetPrerenderContentsForRoute(
    232       int child_id, int route_id) const;
    233 
    234   // Returns a list of all WebContents being prerendered.
    235   const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
    236 
    237   // Checks whether |url| has been recently navigated to.
    238   bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
    239 
    240   // Returns true iff the method given is valid for prerendering.
    241   static bool IsValidHttpMethod(const std::string& method);
    242 
    243   // Returns true iff the scheme of the URL given is valid for prerendering.
    244   static bool DoesURLHaveValidScheme(const GURL& url);
    245 
    246   // Returns true iff the scheme of the subresource URL given is valid for
    247   // prerendering.
    248   static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
    249 
    250   // Returns a Value object containing the active pages being prerendered, and
    251   // a history of pages which were prerendered. The caller is responsible for
    252   // deleting the return value.
    253   base::DictionaryValue* GetAsValue() const;
    254 
    255   // Clears the data indicated by which bits of clear_flags are set.
    256   //
    257   // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are
    258   // cancelled and then deleted, and any WebContents queued for destruction are
    259   // destroyed as well.
    260   //
    261   // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is
    262   // cleared, including any entries newly created by destroying them in
    263   // response to the CLEAR_PRERENDER_CONTENTS flag.
    264   //
    265   // Intended to be used when clearing the cache or history.
    266   void ClearData(int clear_flags);
    267 
    268   // Record a final status of a prerendered page in a histogram.
    269   // This variation allows specifying whether prerendering had been started
    270   // (necessary to flag MatchComplete dummies).
    271   void RecordFinalStatusWithMatchCompleteStatus(
    272       Origin origin,
    273       uint8 experiment_id,
    274       PrerenderContents::MatchCompleteStatus mc_status,
    275       FinalStatus final_status) const;
    276 
    277   // Record a cookie status histogram (see prerender_histograms.h).
    278   void RecordCookieStatus(Origin origin,
    279                           uint8 experiment_id,
    280                           int cookie_status) const;
    281 
    282   // Record a cookie send type histogram (see prerender_histograms.h).
    283   void RecordCookieSendType(Origin origin,
    284                             uint8 experiment_id,
    285                             int cookie_send_type) const;
    286 
    287   // content::NotificationObserver
    288   virtual void Observe(int type,
    289                        const content::NotificationSource& source,
    290                        const content::NotificationDetails& details) OVERRIDE;
    291 
    292   // MediaCaptureDevicesDispatcher::Observer
    293   virtual void OnCreatingAudioStream(int render_process_id,
    294                                      int render_frame_id) OVERRIDE;
    295 
    296   const Config& config() const { return config_; }
    297   Config& mutable_config() { return config_; }
    298 
    299   PrerenderTracker* prerender_tracker() { return prerender_tracker_; }
    300 
    301   bool cookie_store_loaded() { return cookie_store_loaded_; }
    302 
    303   // Adds a condition. This is owned by the PrerenderManager.
    304   void AddCondition(const PrerenderCondition* condition);
    305 
    306   // Records that some visible tab navigated (or was redirected) to the
    307   // provided URL.
    308   void RecordNavigation(const GURL& url);
    309 
    310   // Updates the LoggedInPredictor state to reflect that a login has likely
    311   // on the URL provided.
    312   void RecordLikelyLoginOnURL(const GURL& url);
    313 
    314   // Checks if the LoggedInPredictor shows that the user is likely logged on
    315   // to the site for the URL provided.
    316   void CheckIfLikelyLoggedInOnURL(const GURL& url,
    317                                   bool* lookup_result,
    318                                   bool* database_was_present,
    319                                   const base::Closure& result_cb);
    320 
    321   void OnHistoryServiceDidQueryURL(Origin origin,
    322                                    uint8 experiment_id,
    323                                    bool success,
    324                                    const history::URLRow& url_row,
    325                                    const history::VisitVector& visits);
    326 
    327   Profile* profile() const { return profile_; }
    328 
    329   // Classes which will be tested in prerender unit browser tests should use
    330   // these methods to get times for comparison, so that the test framework can
    331   // mock advancing/retarding time.
    332   virtual base::Time GetCurrentTime() const;
    333   virtual base::TimeTicks GetCurrentTimeTicks() const;
    334 
    335   scoped_refptr<predictors::LoggedInPredictorTable>
    336   logged_in_predictor_table() {
    337     return logged_in_predictor_table_;
    338   }
    339 
    340   PrerenderLocalPredictor* local_predictor() {
    341     return local_predictor_.get();
    342   }
    343 
    344   // Notification that a cookie event happened on a render frame. Will record a
    345   // cookie event for a given render frame, if it is being prerendered.
    346   // If cookies were sent, all cookies must be supplied in |cookie_list|.
    347   static void RecordCookieEvent(int process_id,
    348                                 int frame_id,
    349                                 const GURL& url,
    350                                 const GURL& frame_url,
    351                                 bool is_for_blocking_resource,
    352                                 PrerenderContents::CookieEvent event,
    353                                 const net::CookieList* cookie_list);
    354 
    355   // Arranges for all session storage merges to hang indefinitely. This is used
    356   // to reliably test various swap abort cases.
    357   static void HangSessionStorageMergesForTesting();
    358 
    359   // Notification that a prerender has completed and its bytes should be
    360   // recorded.
    361   void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes);
    362 
    363   // Returns whether prerendering is currently enabled for this manager.
    364   bool IsEnabled() const;
    365 
    366   // Add to the running tally of bytes transferred over the network for this
    367   // profile if prerendering is currently enabled.
    368   void AddProfileNetworkBytesIfEnabled(int64 bytes);
    369 
    370   // Registers a new ProcessHost performing a prerender. Called by
    371   // PrerenderContents.
    372   void AddPrerenderProcessHost(content::RenderProcessHost* process_host);
    373 
    374   // Returns whether or not |process_host| may be reused for new navigations
    375   // from a prerendering perspective. Currently, if Prerender Cookie Stores are
    376   // enabled, prerenders must be in their own processes that may not be shared.
    377   bool MayReuseProcessHost(content::RenderProcessHost* process_host);
    378 
    379   // content::RenderProcessHostObserver implementation.
    380   virtual void RenderProcessHostDestroyed(
    381       content::RenderProcessHost* host) OVERRIDE;
    382 
    383   // To be called once the cookie store for this profile has been loaded.
    384   void OnCookieStoreLoaded();
    385 
    386   // For testing purposes. Issues a callback once the cookie store has been
    387   // loaded.
    388   void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) {
    389     on_cookie_store_loaded_cb_for_testing_ = cb;
    390   }
    391 
    392  protected:
    393   class PendingSwap;
    394   class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
    395    public:
    396     struct OrderByExpiryTime;
    397 
    398     PrerenderData(PrerenderManager* manager,
    399                   PrerenderContents* contents,
    400                   base::TimeTicks expiry_time);
    401 
    402     ~PrerenderData();
    403 
    404     // Turn this PrerenderData into a Match Complete replacement for itself,
    405     // placing the current prerender contents into |to_delete_prerenders_|.
    406     void MakeIntoMatchCompleteReplacement();
    407 
    408     // A new PrerenderHandle has been created for this PrerenderData.
    409     void OnHandleCreated(PrerenderHandle* prerender_handle);
    410 
    411     // The launcher associated with a handle is navigating away from the context
    412     // that launched this prerender. If the prerender is active, it may stay
    413     // alive briefly though, in case we we going through a redirect chain that
    414     // will eventually land at it.
    415     void OnHandleNavigatedAway(PrerenderHandle* prerender_handle);
    416 
    417     // The launcher associated with a handle has taken explicit action to cancel
    418     // this prerender. We may well destroy the prerender in this case if no
    419     // other handles continue to track it.
    420     void OnHandleCanceled(PrerenderHandle* prerender_handle);
    421 
    422     PrerenderContents* contents() { return contents_.get(); }
    423 
    424     PrerenderContents* ReleaseContents();
    425 
    426     int handle_count() const { return handle_count_; }
    427 
    428     base::TimeTicks abandon_time() const { return abandon_time_; }
    429 
    430     base::TimeTicks expiry_time() const { return expiry_time_; }
    431     void set_expiry_time(base::TimeTicks expiry_time) {
    432       expiry_time_ = expiry_time;
    433     }
    434 
    435     void ClearPendingSwap();
    436 
    437     PendingSwap* pending_swap() { return pending_swap_.get(); }
    438     void set_pending_swap(PendingSwap* pending_swap) {
    439       pending_swap_.reset(pending_swap);
    440     }
    441 
    442    private:
    443     PrerenderManager* manager_;
    444     scoped_ptr<PrerenderContents> contents_;
    445 
    446     // The number of distinct PrerenderHandles created for |this|, including
    447     // ones that have called PrerenderData::OnHandleNavigatedAway(), but not
    448     // counting the ones that have called PrerenderData::OnHandleCanceled(). For
    449     // pending prerenders, this will always be 1, since the PrerenderManager
    450     // only merges handles of running prerenders.
    451     int handle_count_;
    452 
    453     // The time when OnHandleNavigatedAway was called.
    454     base::TimeTicks abandon_time_;
    455 
    456     // After this time, this prerender is no longer fresh, and should be
    457     // removed.
    458     base::TimeTicks expiry_time_;
    459 
    460     // If a session storage namespace merge is in progress for this object,
    461     // we need to keep track of various state associated with it.
    462     scoped_ptr<PendingSwap> pending_swap_;
    463 
    464     DISALLOW_COPY_AND_ASSIGN(PrerenderData);
    465   };
    466 
    467   // When a swap can't happen immediately, due to a sesison storage namespace
    468   // merge, there will be a pending swap object while the merge is in
    469   // progress. It retains all the data needed to do the merge, maintains
    470   // throttles for the navigation in the target WebContents that needs to be
    471   // delayed, and handles all conditions which would cancel a pending swap.
    472   class PendingSwap : public content::WebContentsObserver {
    473    public:
    474     PendingSwap(PrerenderManager* manager,
    475                 content::WebContents* target_contents,
    476                 PrerenderData* prerender_data,
    477                 const GURL& url,
    478                 bool should_replace_current_entry);
    479     virtual ~PendingSwap();
    480 
    481     content::WebContents* target_contents() const;
    482     void set_swap_successful(bool swap_successful) {
    483       swap_successful_ = swap_successful;
    484     }
    485 
    486     void BeginSwap();
    487 
    488     // content::WebContentsObserver implementation.
    489     virtual void AboutToNavigateRenderView(
    490         content::RenderViewHost* render_view_host) OVERRIDE;
    491     virtual void ProvisionalChangeToMainFrameUrl(
    492         const GURL& url,
    493         content::RenderFrameHost* render_frame_host) OVERRIDE;
    494     virtual void DidCommitProvisionalLoadForFrame(
    495         int64 frame_id,
    496         const base::string16& frame_unique_name,
    497         bool is_main_frame,
    498         const GURL& validated_url,
    499         content::PageTransition transition_type,
    500         content::RenderViewHost* render_view_host) OVERRIDE;
    501     virtual void DidFailProvisionalLoad(
    502         int64 frame_id,
    503         const base::string16& frame_unique_name,
    504         bool is_main_frame,
    505         const GURL& validated_url,
    506         int error_code,
    507         const base::string16& error_description,
    508         content::RenderViewHost* render_view_host) OVERRIDE;
    509     virtual void WebContentsDestroyed() OVERRIDE;
    510 
    511    private:
    512     void RecordEvent(PrerenderEvent event) const;
    513 
    514     void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result);
    515     void OnMergeTimeout();
    516 
    517     // Prerender parameters.
    518     PrerenderManager* manager_;
    519     PrerenderData* prerender_data_;
    520     GURL url_;
    521     bool should_replace_current_entry_;
    522 
    523     base::TimeTicks start_time_;
    524     PrerenderTracker::ChildRouteIdPair target_route_id_;
    525     bool seen_target_route_id_;
    526     base::OneShotTimer<PendingSwap> merge_timeout_;
    527     bool swap_successful_;
    528 
    529     base::WeakPtrFactory<PendingSwap> weak_factory_;
    530   };
    531 
    532   void SetPrerenderContentsFactory(
    533       PrerenderContents::Factory* prerender_contents_factory);
    534 
    535   // Called by a PrerenderData to signal that the launcher has navigated away
    536   // from the context that launched the prerender. A user may have clicked
    537   // a link in a page containing a <link rel=prerender> element, or the user
    538   // might have committed an omnibox navigation. This is used to possibly
    539   // shorten the TTL of the prerendered page.
    540   void SourceNavigatedAway(PrerenderData* prerender_data);
    541 
    542   // Gets the request context for the profile.
    543   // For unit tests, this will be overriden to return NULL, since it is not
    544   // needed.
    545   virtual net::URLRequestContextGetter* GetURLRequestContext();
    546 
    547  private:
    548   friend class ::InstantSearchPrerendererTest;
    549   friend class PrerenderBrowserTest;
    550   friend class PrerenderContents;
    551   friend class PrerenderHandle;
    552   friend class UnitTestPrerenderManager;
    553 
    554   class OnCloseWebContentsDeleter;
    555   struct NavigationRecord;
    556 
    557   // Time interval before a new prerender is allowed.
    558   static const int kMinTimeBetweenPrerendersMs = 500;
    559 
    560   // Time window for which we record old navigations, in milliseconds.
    561   static const int kNavigationRecordWindowMs = 5000;
    562 
    563   void OnCancelPrerenderHandle(PrerenderData* prerender_data);
    564 
    565   // Adds a prerender for |url| from |referrer| initiated from the process
    566   // |child_id|. The |origin| specifies how the prerender was added. If |size|
    567   // is empty, then PrerenderContents::StartPrerendering will instead use a
    568   // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the
    569   // caller, or NULL.
    570   PrerenderHandle* AddPrerender(
    571       Origin origin,
    572       int child_id,
    573       const GURL& url,
    574       const content::Referrer& referrer,
    575       const gfx::Size& size,
    576       content::SessionStorageNamespace* session_storage_namespace);
    577 
    578   void StartSchedulingPeriodicCleanups();
    579   void StopSchedulingPeriodicCleanups();
    580 
    581   void EvictOldestPrerendersIfNecessary();
    582 
    583   // Deletes stale and cancelled prerendered PrerenderContents, as well as
    584   // WebContents that have been replaced by prerendered WebContents.
    585   // Also identifies and kills PrerenderContents that use too much
    586   // resources.
    587   void PeriodicCleanup();
    588 
    589   // Posts a task to call PeriodicCleanup.  Results in quicker destruction of
    590   // objects.  If |this| is deleted before the task is run, the task will
    591   // automatically be cancelled.
    592   void PostCleanupTask();
    593 
    594   base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
    595   base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
    596 
    597   void DeleteOldEntries();
    598   virtual PrerenderContents* CreatePrerenderContents(
    599       const GURL& url,
    600       const content::Referrer& referrer,
    601       Origin origin,
    602       uint8 experiment_id);
    603 
    604   // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
    605   // after every mutation of active_prerenders_ that can possibly make it
    606   // unsorted (e.g. an insert, or changing an expiry time).
    607   void SortActivePrerenders();
    608 
    609   // Finds the active PrerenderData object for a running prerender matching
    610   // |url| and |session_storage_namespace|.
    611   PrerenderData* FindPrerenderData(
    612       const GURL& url,
    613       const content::SessionStorageNamespace* session_storage_namespace);
    614 
    615   // Finds the active PrerenderData object currently in a PendingSwap for
    616   // |target_contents|. Otherwise, returns NULL.
    617   PrerenderData* FindPrerenderDataForTargetContents(
    618       content::WebContents* target_contents);
    619 
    620   // Given the |prerender_contents|, find the iterator in active_prerenders_
    621   // correponding to the given prerender.
    622   ScopedVector<PrerenderData>::iterator
    623       FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
    624 
    625   bool DoesRateLimitAllowPrerender(Origin origin) const;
    626 
    627   // Deletes old WebContents that have been replaced by prerendered ones.  This
    628   // is needed because they're replaced in a callback from the old WebContents,
    629   // so cannot immediately be deleted.
    630   void DeleteOldWebContents();
    631 
    632   // Cleans up old NavigationRecord's.
    633   void CleanUpOldNavigations();
    634 
    635   // Arrange for the given WebContents to be deleted asap. If deleter is not
    636   // NULL, deletes that as well.
    637   void ScheduleDeleteOldWebContents(content::WebContents* tab,
    638                                     OnCloseWebContentsDeleter* deleter);
    639 
    640   // Adds to the history list.
    641   void AddToHistory(PrerenderContents* contents);
    642 
    643   // Returns a new Value representing the pages currently being prerendered. The
    644   // caller is responsible for delete'ing the return value.
    645   base::Value* GetActivePrerendersAsValue() const;
    646 
    647   // Destroys all pending prerenders using FinalStatus.  Also deletes them as
    648   // well as any swapped out WebContents queued for destruction.
    649   // Used both on destruction, and when clearing the browsing history.
    650   void DestroyAllContents(FinalStatus final_status);
    651 
    652   // Helper function to destroy a PrerenderContents with the specified
    653   // final_status, while at the same time recording that for the MatchComplete
    654   // case, that this prerender would have been used.
    655   void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents,
    656                                          FinalStatus final_status);
    657 
    658   // Records the final status a prerender in the case that a PrerenderContents
    659   // was never created, and also adds a PrerenderHistory entry.
    660   // This is a helper function which will ultimately call
    661   // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
    662   void RecordFinalStatusWithoutCreatingPrerenderContents(
    663       const GURL& url, Origin origin, uint8 experiment_id,
    664       FinalStatus final_status) const;
    665 
    666 
    667   void CookieChanged(ChromeCookieDetails* details);
    668   void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key,
    669                                                bool cookies_exist);
    670   void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map);
    671 
    672   void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const;
    673 
    674   // Swaps a prerender |prerender_data| for |url| into the tab, replacing
    675   // |web_contents|.  Returns the new WebContents that was swapped in, or NULL
    676   // if a swap-in was not possible.  If |should_replace_current_entry| is true,
    677   // the current history entry in |web_contents| is replaced.
    678   content::WebContents* SwapInternal(const GURL& url,
    679                                      content::WebContents* web_contents,
    680                                      PrerenderData* prerender_data,
    681                                      bool should_replace_current_entry);
    682 
    683   // The configuration.
    684   Config config_;
    685 
    686   // Specifies whether prerendering is currently enabled for this
    687   // manager. The value can change dynamically during the lifetime
    688   // of the PrerenderManager.
    689   bool enabled_;
    690 
    691   // The profile that owns this PrerenderManager.
    692   Profile* profile_;
    693 
    694   PrerenderTracker* prerender_tracker_;
    695 
    696   // All running prerenders. Sorted by expiry time, in ascending order.
    697   ScopedVector<PrerenderData> active_prerenders_;
    698 
    699   // Prerenders awaiting deletion.
    700   ScopedVector<PrerenderData> to_delete_prerenders_;
    701 
    702   // List of recent navigations in this profile, sorted by ascending
    703   // navigate_time_.
    704   std::list<NavigationRecord> navigations_;
    705 
    706   scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
    707 
    708   static PrerenderManagerMode mode_;
    709 
    710   // A count of how many prerenders we do per session. Initialized to 0 then
    711   // incremented and emitted to a histogram on each successful prerender.
    712   static int prerenders_per_session_count_;
    713 
    714   // RepeatingTimer to perform periodic cleanups of pending prerendered
    715   // pages.
    716   base::RepeatingTimer<PrerenderManager> repeating_timer_;
    717 
    718   // Track time of last prerender to limit prerender spam.
    719   base::TimeTicks last_prerender_start_time_;
    720 
    721   std::list<content::WebContents*> old_web_contents_list_;
    722 
    723   ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
    724 
    725   scoped_ptr<PrerenderHistory> prerender_history_;
    726 
    727   std::list<const PrerenderCondition*> prerender_conditions_;
    728 
    729   scoped_ptr<PrerenderHistograms> histograms_;
    730 
    731   scoped_ptr<PrerenderLocalPredictor> local_predictor_;
    732 
    733   scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_;
    734 
    735   // Here, we keep the logged in predictor state, but potentially a superset
    736   // of its actual (database-backed) state, since we do not incorporate
    737   // browser data deletion. We do not use this for actual lookups, but only
    738   // to query cookie data for domains we know there was a login before.
    739   // This is required to avoid a large number of cookie lookups on bulk
    740   // deletion of cookies.
    741   scoped_ptr<LoggedInStateMap> logged_in_state_;
    742 
    743   content::NotificationRegistrar notification_registrar_;
    744 
    745   base::CancelableTaskTracker query_url_tracker_;
    746 
    747   // The number of bytes transferred over the network for the profile this
    748   // PrerenderManager is attached to.
    749   int64 profile_network_bytes_;
    750 
    751   // The value of profile_network_bytes_ that was last recorded.
    752   int64 last_recorded_profile_network_bytes_;
    753 
    754   // Set of process hosts being prerendered.
    755   typedef std::set<content::RenderProcessHost*> PrerenderProcessSet;
    756   PrerenderProcessSet prerender_process_hosts_;
    757 
    758   // Indicates whether the cookie store for this profile has fully loaded yet.
    759   bool cookie_store_loaded_;
    760 
    761   base::Closure on_cookie_store_loaded_cb_for_testing_;
    762 
    763   DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
    764 };
    765 
    766 }  // namespace prerender
    767 
    768 #endif  // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
    769