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