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.
5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
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"
41 class InstantSearchPrerendererTest;
42 struct ChromeCookieDetails;
45 class DictionaryValue;
49 struct NavigateParams;
61 class URLRequestContextGetter;
64 #if defined(COMPILER_GCC)
66 namespace BASE_HASH_NAMESPACE {
68 struct hash<content::WebContents*> {
69 std::size_t operator()(content::WebContents* value) const {
70 return reinterpret_cast<std::size_t>(value);
74 } // namespace BASE_HASH_NAMESPACE
80 class PrerenderCondition;
81 class PrerenderHandle;
82 class PrerenderHistograms;
83 class PrerenderHistory;
84 class PrerenderLocalPredictor;
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 {
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,
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.
111 CLEAR_PRERENDER_CONTENTS = 0x1 << 0,
112 CLEAR_PRERENDER_HISTORY = 0x1 << 1,
116 typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap;
118 // ID indicating that no experiment is active.
119 static const uint8 kNoExperiment = 0;
121 // Owned by a Profile object for the lifetime of the profile.
122 PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
124 virtual ~PrerenderManager();
126 // From BrowserContextKeyedService:
127 virtual void Shutdown() OVERRIDE;
129 // Entry points for adding prerenders.
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
137 PrerenderHandle* AddPrerenderFromLinkRelPrerender(
141 const content::Referrer& referrer,
142 const gfx::Size& size);
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(
152 content::SessionStorageNamespace* session_storage_namespace,
153 const gfx::Size& size);
155 PrerenderHandle* AddPrerenderFromLocalPredictor(
157 content::SessionStorageNamespace* session_storage_namespace,
158 const gfx::Size& size);
160 PrerenderHandle* AddPrerenderFromExternalRequest(
162 const content::Referrer& referrer,
163 content::SessionStorageNamespace* session_storage_namespace,
164 const gfx::Size& size);
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
170 PrerenderHandle* AddPrerenderForInstant(
172 content::SessionStorageNamespace* session_storage_namespace,
173 const gfx::Size& size);
175 // Cancels all active prerenders.
176 void CancelAllPrerenders();
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|
182 bool MaybeUsePrerenderedPage(const GURL& url,
183 chrome::NavigateParams* params);
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);
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,
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);
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();
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;
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;
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;
233 // Returns a list of all WebContents being prerendered.
234 const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
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,
240 void MarkWebContentsAsWouldBePrerendered(content::WebContents* web_contents,
242 void MarkWebContentsAsNotPrerendered(content::WebContents* web_contents);
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
248 bool IsWebContentsPrerendered(content::WebContents* web_contents,
249 Origin* origin) const;
250 bool WouldWebContentsBePrerendered(content::WebContents* web_contents,
251 Origin* origin) const;
253 // Checks whether |url| has been recently navigated to.
254 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
256 // Returns true iff the method given is valid for prerendering.
257 static bool IsValidHttpMethod(const std::string& method);
259 // Returns true iff the scheme of the URL given is valid for prerendering.
260 static bool DoesURLHaveValidScheme(const GURL& url);
262 // Returns true iff the scheme of the subresource URL given is valid for
264 static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
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;
271 // Clears the data indicated by which bits of clear_flags are set.
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.
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.
281 // Intended to be used when clearing the cache or history.
282 void ClearData(int clear_flags);
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(
290 PrerenderContents::MatchCompleteStatus mc_status,
291 FinalStatus final_status) const;
293 // Record a cookie status histogram (see prerender_histograms.h).
294 void RecordCookieStatus(Origin origin,
296 int cookie_status) const;
298 // content::NotificationObserver
299 virtual void Observe(int type,
300 const content::NotificationSource& source,
301 const content::NotificationDetails& details) OVERRIDE;
303 // MediaCaptureDevicesDispatcher::Observer
304 virtual void OnCreatingAudioStream(int render_process_id,
305 int render_frame_id) OVERRIDE;
307 const Config& config() const { return config_; }
308 Config& mutable_config() { return config_; }
310 PrerenderTracker* prerender_tracker() { return prerender_tracker_; }
312 // Adds a condition. This is owned by the PrerenderManager.
313 void AddCondition(const PrerenderCondition* condition);
315 // Records that some visible tab navigated (or was redirected) to the
317 void RecordNavigation(const GURL& url);
319 // Updates the LoggedInPredictor state to reflect that a login has likely
320 // on the URL provided.
321 void RecordLikelyLoginOnURL(const GURL& url);
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,
327 bool* database_was_present,
328 const base::Closure& result_cb);
330 void OnHistoryServiceDidQueryURL(Origin origin,
332 CancelableRequestProvider::Handle handle,
334 const history::URLRow* url_row,
335 history::VisitVector* visits);
337 Profile* profile() const { return profile_; }
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;
345 scoped_refptr<predictors::LoggedInPredictorTable>
346 logged_in_predictor_table() {
347 return logged_in_predictor_table_;
350 PrerenderLocalPredictor* local_predictor() {
351 return local_predictor_.get();
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,
360 const GURL& frame_url,
361 PrerenderContents::CookieEvent event,
362 const net::CookieList* cookie_list);
366 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
368 struct OrderByExpiryTime;
370 PrerenderData(PrerenderManager* manager,
371 PrerenderContents* contents,
372 base::TimeTicks expiry_time);
376 // Turn this PrerenderData into a Match Complete replacement for itself,
377 // placing the current prerender contents into |to_delete_prerenders_|.
378 void MakeIntoMatchCompleteReplacement();
380 // A new PrerenderHandle has been created for this PrerenderData.
381 void OnHandleCreated(PrerenderHandle* prerender_handle);
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);
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);
394 PrerenderContents* contents() { return contents_.get(); }
396 PrerenderContents* ReleaseContents();
398 int handle_count() const { return handle_count_; }
400 base::TimeTicks expiry_time() const { return expiry_time_; }
401 void set_expiry_time(base::TimeTicks expiry_time) {
402 expiry_time_ = expiry_time;
405 void ClearPendingSwap();
407 PendingSwap* pending_swap() { return pending_swap_.get(); }
408 void set_pending_swap(PendingSwap* pending_swap) {
409 pending_swap_.reset(pending_swap);
413 PrerenderManager* manager_;
414 scoped_ptr<PrerenderContents> contents_;
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.
423 // After this time, this prerender is no longer fresh, and should be
425 base::TimeTicks expiry_time_;
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_;
431 DISALLOW_COPY_AND_ASSIGN(PrerenderData);
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 {
441 PendingSwap(PrerenderManager* manager,
442 content::WebContents* target_contents,
443 PrerenderData* prerender_data,
445 bool should_replace_current_entry);
446 virtual ~PendingSwap();
448 void set_swap_successful(bool swap_successful) {
449 swap_successful_ = swap_successful;
454 // content::WebContentsObserver implementation.
455 virtual void AboutToNavigateRenderView(
456 content::RenderViewHost* render_view_host) OVERRIDE;
457 virtual void ProvisionalChangeToMainFrameUrl(
459 content::RenderFrameHost* render_frame_host) OVERRIDE;
460 virtual void DidCommitProvisionalLoadForFrame(
462 const base::string16& frame_unique_name,
464 const GURL& validated_url,
465 content::PageTransition transition_type,
466 content::RenderViewHost* render_view_host) OVERRIDE;
467 virtual void DidFailProvisionalLoad(
469 const base::string16& frame_unique_name,
471 const GURL& validated_url,
473 const base::string16& error_description,
474 content::RenderViewHost* render_view_host) OVERRIDE;
475 virtual void WebContentsDestroyed(content::WebContents* web_contents)
479 void RecordEvent(PrerenderEvent event) const;
481 void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result);
482 void OnMergeTimeout();
484 // Prerender parameters.
485 PrerenderManager* manager_;
486 content::WebContents* target_contents_;
487 PrerenderData* prerender_data_;
489 bool should_replace_current_entry_;
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_;
497 base::WeakPtrFactory<PendingSwap> weak_factory_;
500 void SetPrerenderContentsFactory(
501 PrerenderContents::Factory* prerender_contents_factory);
503 // Adds prerenders from the pending Prerenders, called by
504 // PrerenderContents::StartPendingPrerenders.
505 void StartPendingPrerenders(
507 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders,
508 content::SessionStorageNamespace* session_storage_namespace);
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);
518 friend class ::InstantSearchPrerendererTest;
519 friend class PrerenderBrowserTest;
520 friend class PrerenderContents;
521 friend class PrerenderHandle;
522 friend class UnitTestPrerenderManager;
524 class OnCloseWebContentsDeleter;
525 struct NavigationRecord;
527 // For each WebContents that is swapped in, we store a
528 // PrerenderedWebContentsData so that we can track the origin of the
530 struct PrerenderedWebContentsData {
531 explicit PrerenderedWebContentsData(Origin origin);
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.
548 WAITING_FOR_PROVISIONAL_LOAD,
549 SEEN_PROVISIONAL_LOAD,
552 explicit WouldBePrerenderedWebContentsData(Origin origin);
558 // Time interval before a new prerender is allowed.
559 static const int kMinTimeBetweenPrerendersMs = 500;
561 // Time window for which we record old navigations, in milliseconds.
562 static const int kNavigationRecordWindowMs = 5000;
564 void OnCancelPrerenderHandle(PrerenderData* prerender_data);
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
571 PrerenderHandle* AddPrerender(
575 const content::Referrer& referrer,
576 const gfx::Size& size,
577 content::SessionStorageNamespace* session_storage_namespace);
579 void StartSchedulingPeriodicCleanups();
580 void StopSchedulingPeriodicCleanups();
582 void EvictOldestPrerendersIfNecessary();
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
588 void PeriodicCleanup();
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();
595 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
596 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
598 void DeleteOldEntries();
599 virtual PrerenderContents* CreatePrerenderContents(
601 const content::Referrer& referrer,
603 uint8 experiment_id);
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();
610 // Finds the active PrerenderData object for a running prerender matching
611 // |url| and |session_storage_namespace|.
612 PrerenderData* FindPrerenderData(
614 const content::SessionStorageNamespace* session_storage_namespace);
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,
619 PrerenderData* FindPrerenderDataForChildAndRoute(int child_id, int route_id);
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);
626 bool DoesRateLimitAllowPrerender(Origin origin) const;
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();
633 // Cleans up old NavigationRecord's.
634 void CleanUpOldNavigations();
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);
641 // Adds to the history list.
642 void AddToHistory(PrerenderContents* contents);
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;
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);
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);
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,
664 FinalStatus final_status) const;
666 // Returns whether prerendering is currently enabled for this manager.
667 // Must be called on the UI thread.
668 bool IsEnabled() const;
670 void CookieChanged(ChromeCookieDetails* details);
671 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key,
673 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map);
675 void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const;
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);
686 // The configuration.
689 // Specifies whether prerendering is currently enabled for this
690 // manager. The value can change dynamically during the lifetime
691 // of the PrerenderManager.
694 // The profile that owns this PrerenderManager.
697 PrerenderTracker* prerender_tracker_;
699 // All running prerenders. Sorted by expiry time, in ascending order.
700 ScopedVector<PrerenderData> active_prerenders_;
702 // Prerenders awaiting deletion.
703 ScopedVector<PrerenderData> to_delete_prerenders_;
705 // List of recent navigations in this profile, sorted by ascending
707 std::list<NavigationRecord> navigations_;
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
713 base::hash_map<content::WebContents*, PrerenderedWebContentsData>
714 prerendered_web_contents_data_;
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_;
728 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
730 static PrerenderManagerMode mode_;
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_;
736 // RepeatingTimer to perform periodic cleanups of pending prerendered
738 base::RepeatingTimer<PrerenderManager> repeating_timer_;
740 // Track time of last prerender to limit prerender spam.
741 base::TimeTicks last_prerender_start_time_;
743 std::list<content::WebContents*> old_web_contents_list_;
745 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
747 scoped_ptr<PrerenderHistory> prerender_history_;
749 std::list<const PrerenderCondition*> prerender_conditions_;
751 scoped_ptr<PrerenderHistograms> histograms_;
753 scoped_ptr<PrerenderLocalPredictor> local_predictor_;
755 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_;
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_;
765 content::NotificationRegistrar notification_registrar_;
767 CancelableRequestConsumer query_url_consumer_;
769 DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
772 PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
773 int render_process_id);
775 } // namespace prerender
777 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_