blob: a4ed83987bd47f1bbeba1e5e6a4fbc315329318e [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "chrome/browser/predictors/logged_in_predictor_table.h"
#include "chrome/browser/prerender/prerender_config.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_events.h"
#include "chrome/browser/prerender/prerender_final_status.h"
#include "chrome/browser/prerender/prerender_histograms.h"
#include "chrome/browser/prerender/prerender_origin.h"
#include "chrome/browser/prerender/prerender_tracker.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/session_storage_namespace.h"
#include "content/public/browser/web_contents_observer.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_monster.h"
#include "url/gurl.h"
class Profile;
class InstantSearchPrerendererTest;
struct ChromeCookieDetails;
namespace base {
class DictionaryValue;
namespace chrome {
struct NavigateParams;
namespace content {
class WebContents;
namespace gfx {
class Size;
namespace net {
class URLRequestContextGetter;
namespace prerender {
class PrerenderCondition;
class PrerenderHandle;
class PrerenderHistory;
class PrerenderLocalPredictor;
// PrerenderManager is responsible for initiating and keeping prerendered
// views of web pages. All methods must be called on the UI thread unless
// indicated otherwise.
class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
public base::NonThreadSafe,
public content::NotificationObserver,
public content::RenderProcessHostObserver,
public KeyedService,
public MediaCaptureDevicesDispatcher::Observer {
// NOTE: New values need to be appended, since they are used in histograms.
enum PrerenderManagerMode {
// One or more of these flags must be passed to ClearData() to specify just
// what data to clear. See function declaration for more information.
enum ClearFlags {
CLEAR_MAX = 0x1 << 2
typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap;
// ID indicating that no experiment is active.
static const uint8 kNoExperiment = 0;
// Owned by a Profile object for the lifetime of the profile.
PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
virtual ~PrerenderManager();
// From KeyedService:
virtual void Shutdown() OVERRIDE;
// Entry points for adding prerenders.
// Adds a prerender for |url| if valid. |process_id| and |route_id| identify
// the RenderView that the prerender request came from. If |size| is empty, a
// default from the PrerenderConfig is used. Returns a caller-owned
// PrerenderHandle* if the URL was added, NULL if it was not. If the launching
// RenderView is itself prerendering, the prerender is added as a pending
// prerender.
PrerenderHandle* AddPrerenderFromLinkRelPrerender(
int process_id,
int route_id,
const GURL& url,
uint32 rel_types,
const content::Referrer& referrer,
const gfx::Size& size);
// Adds a prerender for |url| if valid. As the prerender request is coming
// from a source without a RenderViewHost (i.e., the omnibox) we don't have a
// child or route id, or a referrer. This method uses sensible values for
// those. The |session_storage_namespace| matches the namespace of the active
// tab at the time the prerender is generated from the omnibox. Returns a
// caller-owned PrerenderHandle*, or NULL.
PrerenderHandle* AddPrerenderFromOmnibox(
const GURL& url,
content::SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size);
PrerenderHandle* AddPrerenderFromLocalPredictor(
const GURL& url,
content::SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size);
PrerenderHandle* AddPrerenderFromExternalRequest(
const GURL& url,
const content::Referrer& referrer,
content::SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size);
// Adds a prerender for Instant Search |url| if valid. The
// |session_storage_namespace| matches the namespace of the active tab at the
// time the prerender is generated. Returns a caller-owned PrerenderHandle* or
// NULL.
PrerenderHandle* AddPrerenderForInstant(
const GURL& url,
content::SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size);
// Cancels all active prerenders.
void CancelAllPrerenders();
// If |url| matches a valid prerendered page and |params| are compatible, try
// to swap it and merge browsing histories. Returns |true| and updates
// |params->target_contents| if a prerendered page is swapped in, |false|
// otherwise.
bool MaybeUsePrerenderedPage(const GURL& url,
chrome::NavigateParams* params);
// Moves a PrerenderContents to the pending delete list from the list of
// active prerenders when prerendering should be cancelled.
virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
FinalStatus final_status);
// Records the page load time for a prerender that wasn't swapped in.
void RecordPageLoadTimeNotSwappedIn(Origin origin,
base::TimeDelta page_load_time,
const GURL& url);
// Records the perceived page load time for a page - effectively the time from
// when the user navigates to a page to when it finishes loading. The actual
// load may have started prior to navigation due to prerender hints.
// This must be called on the UI thread.
// |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value
// outside that range indicating that it doesn't apply.
void RecordPerceivedPageLoadTime(
Origin origin,
NavigationType navigation_type,
base::TimeDelta perceived_page_load_time,
double fraction_plt_elapsed_at_swap_in,
const GURL& url);
// Set whether prerendering is currently enabled for this manager.
// Must be called on the UI thread.
// If |enabled| is false, existing prerendered pages will still persist until
// they time out, but new ones will not be generated.
void set_enabled(bool enabled);
static PrerenderManagerMode GetMode();
static void SetMode(PrerenderManagerMode mode);
static const char* GetModeString();
static bool IsPrerenderingPossible();
static bool ActuallyPrerendering();
static bool IsControlGroup(uint8 experiment_id);
static bool IsNoUseGroup();
// Query the list of current prerender pages to see if the given web contents
// is prerendering a page. The optional parameter |origin| is an output
// parameter which, if a prerender is found, is set to the Origin of the
// prerender |web_contents|.
bool IsWebContentsPrerendering(const content::WebContents* web_contents,
Origin* origin) const;
// Whether the PrerenderManager has an active prerender with the given url and
// SessionStorageNamespace associated with the given WebContens.
bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const;
// Returns the PrerenderContents object for the given web_contents, otherwise
// returns NULL. Note that the PrerenderContents may have been Destroy()ed,
// but not yet deleted.
PrerenderContents* GetPrerenderContents(
const content::WebContents* web_contents) const;
// Returns the PrerenderContents object for a given child_id, route_id pair,
// otherwise returns NULL. Note that the PrerenderContents may have been
// Destroy()ed, but not yet deleted.
virtual PrerenderContents* GetPrerenderContentsForRoute(
int child_id, int route_id) const;
// Returns a list of all WebContents being prerendered.
const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
// Checks whether |url| has been recently navigated to.
bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
// Returns true iff the method given is valid for prerendering.
static bool IsValidHttpMethod(const std::string& method);
// Returns true iff the scheme of the URL given is valid for prerendering.
static bool DoesURLHaveValidScheme(const GURL& url);
// Returns true iff the scheme of the subresource URL given is valid for
// prerendering.
static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
// Returns a Value object containing the active pages being prerendered, and
// a history of pages which were prerendered. The caller is responsible for
// deleting the return value.
base::DictionaryValue* GetAsValue() const;
// Clears the data indicated by which bits of clear_flags are set.
// If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are
// cancelled and then deleted, and any WebContents queued for destruction are
// destroyed as well.
// If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is
// cleared, including any entries newly created by destroying them in
// response to the CLEAR_PRERENDER_CONTENTS flag.
// Intended to be used when clearing the cache or history.
void ClearData(int clear_flags);
// Record a final status of a prerendered page in a histogram.
// This variation allows specifying whether prerendering had been started
// (necessary to flag MatchComplete dummies).
void RecordFinalStatusWithMatchCompleteStatus(
Origin origin,
uint8 experiment_id,
PrerenderContents::MatchCompleteStatus mc_status,
FinalStatus final_status) const;
// Record a cookie status histogram (see prerender_histograms.h).
void RecordCookieStatus(Origin origin,
uint8 experiment_id,
int cookie_status) const;
// Record a cookie send type histogram (see prerender_histograms.h).
void RecordCookieSendType(Origin origin,
uint8 experiment_id,
int cookie_send_type) const;
// content::NotificationObserver
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// MediaCaptureDevicesDispatcher::Observer
virtual void OnCreatingAudioStream(int render_process_id,
int render_frame_id) OVERRIDE;
const Config& config() const { return config_; }
Config& mutable_config() { return config_; }
PrerenderTracker* prerender_tracker() { return prerender_tracker_; }
bool cookie_store_loaded() { return cookie_store_loaded_; }
// Adds a condition. This is owned by the PrerenderManager.
void AddCondition(const PrerenderCondition* condition);
// Records that some visible tab navigated (or was redirected) to the
// provided URL.
void RecordNavigation(const GURL& url);
// Updates the LoggedInPredictor state to reflect that a login has likely
// on the URL provided.
void RecordLikelyLoginOnURL(const GURL& url);
// Checks if the LoggedInPredictor shows that the user is likely logged on
// to the site for the URL provided.
void CheckIfLikelyLoggedInOnURL(const GURL& url,
bool* lookup_result,
bool* database_was_present,
const base::Closure& result_cb);
void OnHistoryServiceDidQueryURL(Origin origin,
uint8 experiment_id,
bool success,
const history::URLRow& url_row,
const history::VisitVector& visits);
Profile* profile() const { return profile_; }
// Classes which will be tested in prerender unit browser tests should use
// these methods to get times for comparison, so that the test framework can
// mock advancing/retarding time.
virtual base::Time GetCurrentTime() const;
virtual base::TimeTicks GetCurrentTimeTicks() const;
logged_in_predictor_table() {
return logged_in_predictor_table_;
PrerenderLocalPredictor* local_predictor() {
return local_predictor_.get();
// Notification that a cookie event happened on a render frame. Will record a
// cookie event for a given render frame, if it is being prerendered.
// If cookies were sent, all cookies must be supplied in |cookie_list|.
static void RecordCookieEvent(int process_id,
int frame_id,
const GURL& url,
const GURL& frame_url,
bool is_for_blocking_resource,
PrerenderContents::CookieEvent event,
const net::CookieList* cookie_list);
// Arranges for all session storage merges to hang indefinitely. This is used
// to reliably test various swap abort cases.
static void HangSessionStorageMergesForTesting();
// Notification that a prerender has completed and its bytes should be
// recorded.
void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes);
// Returns whether prerendering is currently enabled for this manager.
bool IsEnabled() const;
// Add to the running tally of bytes transferred over the network for this
// profile if prerendering is currently enabled.
void AddProfileNetworkBytesIfEnabled(int64 bytes);
// Registers a new ProcessHost performing a prerender. Called by
// PrerenderContents.
void AddPrerenderProcessHost(content::RenderProcessHost* process_host);
// Returns whether or not |process_host| may be reused for new navigations
// from a prerendering perspective. Currently, if Prerender Cookie Stores are
// enabled, prerenders must be in their own processes that may not be shared.
bool MayReuseProcessHost(content::RenderProcessHost* process_host);
// content::RenderProcessHostObserver implementation.
virtual void RenderProcessHostDestroyed(
content::RenderProcessHost* host) OVERRIDE;
// To be called once the cookie store for this profile has been loaded.
void OnCookieStoreLoaded();
// For testing purposes. Issues a callback once the cookie store has been
// loaded.
void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) {
on_cookie_store_loaded_cb_for_testing_ = cb;
class PendingSwap;
class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
struct OrderByExpiryTime;
PrerenderData(PrerenderManager* manager,
PrerenderContents* contents,
base::TimeTicks expiry_time);
// Turn this PrerenderData into a Match Complete replacement for itself,
// placing the current prerender contents into |to_delete_prerenders_|.
void MakeIntoMatchCompleteReplacement();
// A new PrerenderHandle has been created for this PrerenderData.
void OnHandleCreated(PrerenderHandle* prerender_handle);
// The launcher associated with a handle is navigating away from the context
// that launched this prerender. If the prerender is active, it may stay
// alive briefly though, in case we we going through a redirect chain that
// will eventually land at it.
void OnHandleNavigatedAway(PrerenderHandle* prerender_handle);
// The launcher associated with a handle has taken explicit action to cancel
// this prerender. We may well destroy the prerender in this case if no
// other handles continue to track it.
void OnHandleCanceled(PrerenderHandle* prerender_handle);
PrerenderContents* contents() { return contents_.get(); }
PrerenderContents* ReleaseContents();
int handle_count() const { return handle_count_; }
base::TimeTicks abandon_time() const { return abandon_time_; }
base::TimeTicks expiry_time() const { return expiry_time_; }
void set_expiry_time(base::TimeTicks expiry_time) {
expiry_time_ = expiry_time;
void ClearPendingSwap();
PendingSwap* pending_swap() { return pending_swap_.get(); }
void set_pending_swap(PendingSwap* pending_swap) {
PrerenderManager* manager_;
scoped_ptr<PrerenderContents> contents_;
// The number of distinct PrerenderHandles created for |this|, including
// ones that have called PrerenderData::OnHandleNavigatedAway(), but not
// counting the ones that have called PrerenderData::OnHandleCanceled(). For
// pending prerenders, this will always be 1, since the PrerenderManager
// only merges handles of running prerenders.
int handle_count_;
// The time when OnHandleNavigatedAway was called.
base::TimeTicks abandon_time_;
// After this time, this prerender is no longer fresh, and should be
// removed.
base::TimeTicks expiry_time_;
// If a session storage namespace merge is in progress for this object,
// we need to keep track of various state associated with it.
scoped_ptr<PendingSwap> pending_swap_;
// When a swap can't happen immediately, due to a sesison storage namespace
// merge, there will be a pending swap object while the merge is in
// progress. It retains all the data needed to do the merge, maintains
// throttles for the navigation in the target WebContents that needs to be
// delayed, and handles all conditions which would cancel a pending swap.
class PendingSwap : public content::WebContentsObserver {
PendingSwap(PrerenderManager* manager,
content::WebContents* target_contents,
PrerenderData* prerender_data,
const GURL& url,
bool should_replace_current_entry);
virtual ~PendingSwap();
content::WebContents* target_contents() const;
void set_swap_successful(bool swap_successful) {
swap_successful_ = swap_successful;
void BeginSwap();
// content::WebContentsObserver implementation.
virtual void AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void ProvisionalChangeToMainFrameUrl(
const GURL& url,
content::RenderFrameHost* render_frame_host) OVERRIDE;
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
content::PageTransition transition_type,
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void DidFailProvisionalLoad(
int64 frame_id,
const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void WebContentsDestroyed() OVERRIDE;
void RecordEvent(PrerenderEvent event) const;
void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result);
void OnMergeTimeout();
// Prerender parameters.
PrerenderManager* manager_;
PrerenderData* prerender_data_;
GURL url_;
bool should_replace_current_entry_;
base::TimeTicks start_time_;
PrerenderTracker::ChildRouteIdPair target_route_id_;
bool seen_target_route_id_;
base::OneShotTimer<PendingSwap> merge_timeout_;
bool swap_successful_;
base::WeakPtrFactory<PendingSwap> weak_factory_;
void SetPrerenderContentsFactory(
PrerenderContents::Factory* prerender_contents_factory);
// Called by a PrerenderData to signal that the launcher has navigated away
// from the context that launched the prerender. A user may have clicked
// a link in a page containing a <link rel=prerender> element, or the user
// might have committed an omnibox navigation. This is used to possibly
// shorten the TTL of the prerendered page.
void SourceNavigatedAway(PrerenderData* prerender_data);
// Gets the request context for the profile.
// For unit tests, this will be overriden to return NULL, since it is not
// needed.
virtual net::URLRequestContextGetter* GetURLRequestContext();
friend class ::InstantSearchPrerendererTest;
friend class PrerenderBrowserTest;
friend class PrerenderContents;
friend class PrerenderHandle;
friend class UnitTestPrerenderManager;
class OnCloseWebContentsDeleter;
struct NavigationRecord;
// Time interval before a new prerender is allowed.
static const int kMinTimeBetweenPrerendersMs = 500;
// Time window for which we record old navigations, in milliseconds.
static const int kNavigationRecordWindowMs = 5000;
void OnCancelPrerenderHandle(PrerenderData* prerender_data);
// Adds a prerender for |url| from |referrer| initiated from the process
// |child_id|. The |origin| specifies how the prerender was added. If |size|
// is empty, then PrerenderContents::StartPrerendering will instead use a
// default from PrerenderConfig. Returns a PrerenderHandle*, owned by the
// caller, or NULL.
PrerenderHandle* AddPrerender(
Origin origin,
int child_id,
const GURL& url,
const content::Referrer& referrer,
const gfx::Size& size,
content::SessionStorageNamespace* session_storage_namespace);
void StartSchedulingPeriodicCleanups();
void StopSchedulingPeriodicCleanups();
void EvictOldestPrerendersIfNecessary();
// Deletes stale and cancelled prerendered PrerenderContents, as well as
// WebContents that have been replaced by prerendered WebContents.
// Also identifies and kills PrerenderContents that use too much
// resources.
void PeriodicCleanup();
// Posts a task to call PeriodicCleanup. Results in quicker destruction of
// objects. If |this| is deleted before the task is run, the task will
// automatically be cancelled.
void PostCleanupTask();
base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
void DeleteOldEntries();
virtual PrerenderContents* CreatePrerenderContents(
const GURL& url,
const content::Referrer& referrer,
Origin origin,
uint8 experiment_id);
// Insures the |active_prerenders_| are sorted by increasing expiry time. Call
// after every mutation of active_prerenders_ that can possibly make it
// unsorted (e.g. an insert, or changing an expiry time).
void SortActivePrerenders();
// Finds the active PrerenderData object for a running prerender matching
// |url| and |session_storage_namespace|.
PrerenderData* FindPrerenderData(
const GURL& url,
const content::SessionStorageNamespace* session_storage_namespace);
// Finds the active PrerenderData object currently in a PendingSwap for
// |target_contents|. Otherwise, returns NULL.
PrerenderData* FindPrerenderDataForTargetContents(
content::WebContents* target_contents);
// Given the |prerender_contents|, find the iterator in active_prerenders_
// correponding to the given prerender.
FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
bool DoesRateLimitAllowPrerender(Origin origin) const;
// Deletes old WebContents that have been replaced by prerendered ones. This
// is needed because they're replaced in a callback from the old WebContents,
// so cannot immediately be deleted.
void DeleteOldWebContents();
// Cleans up old NavigationRecord's.
void CleanUpOldNavigations();
// Arrange for the given WebContents to be deleted asap. If deleter is not
// NULL, deletes that as well.
void ScheduleDeleteOldWebContents(content::WebContents* tab,
OnCloseWebContentsDeleter* deleter);
// Adds to the history list.
void AddToHistory(PrerenderContents* contents);
// Returns a new Value representing the pages currently being prerendered. The
// caller is responsible for delete'ing the return value.
base::Value* GetActivePrerendersAsValue() const;
// Destroys all pending prerenders using FinalStatus. Also deletes them as
// well as any swapped out WebContents queued for destruction.
// Used both on destruction, and when clearing the browsing history.
void DestroyAllContents(FinalStatus final_status);
// Helper function to destroy a PrerenderContents with the specified
// final_status, while at the same time recording that for the MatchComplete
// case, that this prerender would have been used.
void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents,
FinalStatus final_status);
// Records the final status a prerender in the case that a PrerenderContents
// was never created, and also adds a PrerenderHistory entry.
// This is a helper function which will ultimately call
// RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
void RecordFinalStatusWithoutCreatingPrerenderContents(
const GURL& url, Origin origin, uint8 experiment_id,
FinalStatus final_status) const;
void CookieChanged(ChromeCookieDetails* details);
void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key,
bool cookies_exist);
void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map);
void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const;
// Swaps a prerender |prerender_data| for |url| into the tab, replacing
// |web_contents|. Returns the new WebContents that was swapped in, or NULL
// if a swap-in was not possible. If |should_replace_current_entry| is true,
// the current history entry in |web_contents| is replaced.
content::WebContents* SwapInternal(const GURL& url,
content::WebContents* web_contents,
PrerenderData* prerender_data,
bool should_replace_current_entry);
// The configuration.
Config config_;
// Specifies whether prerendering is currently enabled for this
// manager. The value can change dynamically during the lifetime
// of the PrerenderManager.
bool enabled_;
// The profile that owns this PrerenderManager.
Profile* profile_;
PrerenderTracker* prerender_tracker_;
// All running prerenders. Sorted by expiry time, in ascending order.
ScopedVector<PrerenderData> active_prerenders_;
// Prerenders awaiting deletion.
ScopedVector<PrerenderData> to_delete_prerenders_;
// List of recent navigations in this profile, sorted by ascending
// navigate_time_.
std::list<NavigationRecord> navigations_;
scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
static PrerenderManagerMode mode_;
// A count of how many prerenders we do per session. Initialized to 0 then
// incremented and emitted to a histogram on each successful prerender.
static int prerenders_per_session_count_;
// RepeatingTimer to perform periodic cleanups of pending prerendered
// pages.
base::RepeatingTimer<PrerenderManager> repeating_timer_;
// Track time of last prerender to limit prerender spam.
base::TimeTicks last_prerender_start_time_;
std::list<content::WebContents*> old_web_contents_list_;
ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
scoped_ptr<PrerenderHistory> prerender_history_;
std::list<const PrerenderCondition*> prerender_conditions_;
scoped_ptr<PrerenderHistograms> histograms_;
scoped_ptr<PrerenderLocalPredictor> local_predictor_;
scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_;
// Here, we keep the logged in predictor state, but potentially a superset
// of its actual (database-backed) state, since we do not incorporate
// browser data deletion. We do not use this for actual lookups, but only
// to query cookie data for domains we know there was a login before.
// This is required to avoid a large number of cookie lookups on bulk
// deletion of cookies.
scoped_ptr<LoggedInStateMap> logged_in_state_;
content::NotificationRegistrar notification_registrar_;
base::CancelableTaskTracker query_url_tracker_;
// The number of bytes transferred over the network for the profile this
// PrerenderManager is attached to.
int64 profile_network_bytes_;
// The value of profile_network_bytes_ that was last recorded.
int64 last_recorded_profile_network_bytes_;
// Set of process hosts being prerendered.
typedef std::set<content::RenderProcessHost*> PrerenderProcessSet;
PrerenderProcessSet prerender_process_hosts_;
// Indicates whether the cookie store for this profile has fully loaded yet.
bool cookie_store_loaded_;
base::Closure on_cookie_store_loaded_cb_for_testing_;
} // namespace prerender