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