// Copyright 2013 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. #ifndef COMPONENTS_PRECACHE_CONTENT_PRECACHE_MANAGER_H_ #define COMPONENTS_PRECACHE_CONTENT_PRECACHE_MANAGER_H_ #include #include #include #include #include #include #include #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "components/history/core/browser/history_types.h" #include "components/keyed_service/core/keyed_service.h" #include "components/precache/core/precache_fetcher.h" #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache.h" #include "url/gurl.h" namespace base { class FilePath; class Time; class TimeDelta; } namespace content { class BrowserContext; } namespace data_reduction_proxy { class DataReductionProxySettings; } namespace history { class HistoryService; } namespace net { class HttpResponseInfo; } namespace syncer { class SyncService; } namespace precache { class PrecacheDatabase; class PrecacheUnfinishedWork; extern const char kPrecacheFieldTrialName[]; // Visible for test. extern const char kMinCacheSizeParam[]; size_t NumTopHosts(); // Class that manages all precaching-related activities. Owned by the // BrowserContext that it is constructed for. Use // PrecacheManagerFactory::GetForBrowserContext to get an instance of this // class. All methods must be called on the UI thread unless indicated // otherwise. // TODO(sclittle): Delete precache history when browsing history is deleted. // http://crbug.com/326549 class PrecacheManager : public KeyedService, public PrecacheFetcher::PrecacheDelegate, public base::SupportsWeakPtr { public: typedef base::Callback PrecacheCompletionCallback; PrecacheManager(content::BrowserContext* browser_context, const syncer::SyncService* sync_service, const history::HistoryService* history_service, const data_reduction_proxy::DataReductionProxySettings* data_reduction_proxy_settings, const base::FilePath& db_path, std::unique_ptr precache_database); ~PrecacheManager() override; // Returns true if the client is in the experiment group -- that is, // precaching is allowed based on user settings, and enabled as part of a // field trial or by commandline flag. Virtual for testing. virtual bool IsInExperimentGroup() const; // Returns true if the client is in the control group -- that is, precaching // is allowed based on user settings, and the browser is in the control group // of the field trial. Virtual for testing. virtual bool IsInControlGroup() const; // Returns true if precaching is allowed based on user settings. Virtual for // testing. virtual bool IsPrecachingAllowed() const; // Starts precaching resources that the user is predicted to fetch in the // future. If precaching is already currently in progress, then this method // does nothing. The |precache_completion_callback| will be passed true when // precaching finishes, and passed false when precaching abort due to failed // preconditions, but will not be run if precaching is canceled. void StartPrecaching( const PrecacheCompletionCallback& precache_completion_callback); // Cancels precaching if it is in progress. void CancelPrecaching(); // Returns true if precaching is currently in progress, or false otherwise. bool IsPrecaching() const; // Posts a task to the DB thread to delete all history entries from the // database. Does not wait for completion of this task. void ClearHistory(); // Update precache about an URL being fetched. Metrics related to precache are // updated and any ongoing precache will be cancelled if this is an user // initiated request. Should be called on UI thread. void UpdatePrecacheMetricsAndState( const GURL& url, const GURL& referrer, const base::TimeDelta& latency, const base::Time& fetch_time, const net::HttpResponseInfo& info, int64_t size, bool is_user_traffic, const base::Callback& register_synthetic_trial); private: friend class PrecacheManagerTest; FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, DeleteExpiredPrecacheHistory); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchDuringPrecaching); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchHTTP); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchHTTPS); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchInTopHosts); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchWithEmptyURL); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchWithNonHTTP); FRIEND_TEST_ALL_PREFIXES(PrecacheManagerTest, RecordStatsForFetchWithSizeZero); enum class AllowedType { ALLOWED, DISALLOWED, PENDING }; // From KeyedService. void Shutdown() override; // From PrecacheFetcher::PrecacheDelegate. void OnDone() override; // Registers the precache synthetic field trial for users whom the precache // task was run recently. |last_precache_time| is the last time precache task // was run. void RegisterSyntheticFieldTrial(const base::Time last_precache_time); // Callback when fetching unfinished work from storage is done. void OnGetUnfinishedWorkDone( std::unique_ptr unfinished_work); // From history::HistoryService::TopHosts. void OnHostsReceived(const history::TopHostsList& host_counts); // Initializes and Starts a PrecacheFetcher with unfinished work. void InitializeAndStartFetcher(); // From history::HistoryService::TopHosts. Used for the control group, which // gets the list of TopHosts for metrics purposes, but otherwise does nothing. void OnHostsReceivedThenDone(const history::TopHostsList& host_counts); // Chain of callbacks for StartPrecaching that make sure that we only precache // if there is a cache big enough. void PrecacheIfCacheIsBigEnough( scoped_refptr url_request_context_getter); void OnCacheBackendReceived(int net_error_code); void OnCacheSizeReceived(int cache_size_bytes); void OnCacheSizeReceivedInUIThread(int cache_size_bytes); // Returns true if precaching is allowed for the browser context. AllowedType PrecachingAllowed() const; // Update precache-related metrics in response to a URL being fetched. void RecordStatsForFetch( const GURL& url, const GURL& referrer, const base::TimeDelta& latency, const base::Time& fetch_time, const net::HttpResponseInfo& info, int64_t size, const base::Callback& register_synthetic_trial, base::Time last_precache_time); // Update precache-related metrics in response to a URL being fetched. Called // by RecordStatsForFetch() by way of an asynchronous HistoryService callback. void RecordStatsForFetchInternal(const GURL& url, const std::string& referrer_host, const base::TimeDelta& latency, const base::Time& fetch_time, const net::HttpResponseInfo& info, int64_t size, int host_rank); // The browser context that owns this PrecacheManager. content::BrowserContext* const browser_context_; // The sync service corresponding to the browser context. Used to determine // whether precache can run. May be null. const syncer::SyncService* const sync_service_; // The history service corresponding to the browser context. Used to determine // the list of top hosts. May be null. const history::HistoryService* const history_service_; // The data reduction proxy settings object corresponding to the browser // context. Used to determine if the proxy is enabled. const data_reduction_proxy::DataReductionProxySettings* const data_reduction_proxy_settings_; // The PrecacheFetcher used to precache resources. Should only be used on the // UI thread. std::unique_ptr precache_fetcher_; // The callback that will be run if precaching finishes without being // canceled. PrecacheCompletionCallback precache_completion_callback_; // The PrecacheDatabase for tracking precache metrics. Should only be used on // the DB thread. std::unique_ptr precache_database_; // Flag indicating whether or not precaching is currently in progress. bool is_precaching_; // Pointer to the backend of the cache. Required to get the size of the cache. // It is not owned and it is reset on demand via callbacks. // It should only be accessed from the IO thread. disk_cache::Backend* cache_backend_; // The minimum cache size allowed for precaching. Initialized by // StartPrecaching and read by OnCacheSizeReceivedInUIThread. int min_cache_size_bytes_; // Work that hasn't yet finished. std::unique_ptr unfinished_work_; DISALLOW_COPY_AND_ASSIGN(PrecacheManager); }; } // namespace precache #endif // COMPONENTS_PRECACHE_CONTENT_PRECACHE_MANAGER_H_