blob: d4bff9e9f662684cce5963c1a48fbda776990f30 [file] [log] [blame]
// 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 <stddef.h>
#include <stdint.h>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#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<PrecacheManager> {
public:
typedef base::Callback<void(bool)> 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<PrecacheDatabase> 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<void(base::Time)>& 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<PrecacheUnfinishedWork> 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<net::URLRequestContextGetter> 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<void(base::Time)>& 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<PrecacheFetcher> 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<PrecacheDatabase> 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<PrecacheUnfinishedWork> unfinished_work_;
DISALLOW_COPY_AND_ASSIGN(PrecacheManager);
};
} // namespace precache
#endif // COMPONENTS_PRECACHE_CONTENT_PRECACHE_MANAGER_H_