• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
config()296   const Config& config() const { return config_; }
mutable_config()297   Config& mutable_config() { return config_; }
298 
prerender_tracker()299   PrerenderTracker* prerender_tracker() { return prerender_tracker_; }
300 
cookie_store_loaded()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 
profile()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>
logged_in_predictor_table()336   logged_in_predictor_table() {
337     return logged_in_predictor_table_;
338   }
339 
local_predictor()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.
set_on_cookie_store_loaded_cb_for_testing(base::Closure cb)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 
contents()422     PrerenderContents* contents() { return contents_.get(); }
423 
424     PrerenderContents* ReleaseContents();
425 
handle_count()426     int handle_count() const { return handle_count_; }
427 
abandon_time()428     base::TimeTicks abandon_time() const { return abandon_time_; }
429 
expiry_time()430     base::TimeTicks expiry_time() const { return expiry_time_; }
set_expiry_time(base::TimeTicks expiry_time)431     void set_expiry_time(base::TimeTicks expiry_time) {
432       expiry_time_ = expiry_time;
433     }
434 
435     void ClearPendingSwap();
436 
pending_swap()437     PendingSwap* pending_swap() { return pending_swap_.get(); }
set_pending_swap(PendingSwap * pending_swap)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;
set_swap_successful(bool swap_successful)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