| Index: components/precache/content/precache_manager.cc
|
| diff --git a/components/precache/content/precache_manager.cc b/components/precache/content/precache_manager.cc
|
| index 1d2ddb653b7742cb2d7257d3ea1aeaa37f5aba25..dbeedde008050f3d6e42238a417f3836f5413aac 100644
|
| --- a/components/precache/content/precache_manager.cc
|
| +++ b/components/precache/content/precache_manager.cc
|
| @@ -10,7 +10,6 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| -#include "base/files/file_path.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/field_trial.h"
|
| #include "base/strings/string_util.h"
|
| @@ -18,6 +17,7 @@
|
| #include "components/history/core/browser/history_service.h"
|
| #include "components/precache/core/precache_database.h"
|
| #include "components/precache/core/precache_switches.h"
|
| +#include "components/precache/core/proto/unfinished_work.pb.h"
|
| #include "components/prefs/pref_service.h"
|
| #include "components/sync_driver/sync_service.h"
|
| #include "components/variations/variations_associated_data.h"
|
| @@ -48,15 +48,14 @@ size_t NumTopHosts() {
|
| PrecacheManager::PrecacheManager(
|
| content::BrowserContext* browser_context,
|
| const sync_driver::SyncService* const sync_service,
|
| - const history::HistoryService* const history_service)
|
| + const history::HistoryService* const history_service,
|
| + const base::FilePath& db_path,
|
| + std::unique_ptr<PrecacheDatabase> precache_database)
|
| : browser_context_(browser_context),
|
| sync_service_(sync_service),
|
| history_service_(history_service),
|
| - precache_database_(new PrecacheDatabase()),
|
| is_precaching_(false) {
|
| - base::FilePath db_path(browser_context_->GetPath().Append(
|
| - base::FilePath(FILE_PATH_LITERAL("PrecacheDatabase"))));
|
| -
|
| + precache_database_ = std::move(precache_database);
|
| BrowserThread::PostTask(
|
| BrowserThread::DB, FROM_HERE,
|
| base::Bind(base::IgnoreResult(&PrecacheDatabase::Init),
|
| @@ -122,9 +121,31 @@ void PrecacheManager::StartPrecaching(
|
| }
|
| precache_completion_callback_ = precache_completion_callback;
|
|
|
| - if (IsInExperimentGroup()) {
|
| - is_precaching_ = true;
|
| + is_precaching_ = true;
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::DB,
|
| + FROM_HERE,
|
| + base::Bind(&PrecacheDatabase::GetUnfinishedWork,
|
| + base::Unretained(precache_database_.get())),
|
| + base::Bind(&PrecacheManager::OnGetUnfinishedWorkDone, AsWeakPtr()));
|
| +}
|
|
|
| +void PrecacheManager::OnGetUnfinishedWorkDone(
|
| + std::unique_ptr<PrecacheUnfinishedWork> unfinished_work) {
|
| + if (!unfinished_work->has_start_time() ||
|
| + base::Time::Now() - base::Time::FromInternalValue(
|
| + unfinished_work->start_time()) > base::TimeDelta::FromHours(6)) {
|
| + PrecacheFetcher::RecordCompletionStatistics(
|
| + *unfinished_work,
|
| + unfinished_work->manifest_size(),
|
| + unfinished_work->resource_size());
|
| + unfinished_work.reset(new PrecacheUnfinishedWork());
|
| + unfinished_work->set_start_time(base::Time::Now().ToInternalValue());
|
| + }
|
| + unfinished_work_ = std::move(unfinished_work);
|
| + bool needs_top_hosts = unfinished_work_->top_host_size() == 0;
|
| +
|
| + if (IsInExperimentGroup()) {
|
| BrowserThread::PostTask(
|
| BrowserThread::DB, FROM_HERE,
|
| base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory,
|
| @@ -134,25 +155,28 @@ void PrecacheManager::StartPrecaching(
|
| // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further
|
| // bound by the value of PrecacheConfigurationSettings.top_sites_count, as
|
| // retrieved from the server.
|
| - history_service_->TopHosts(
|
| - NumTopHosts(),
|
| - base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr()));
|
| + if (needs_top_hosts) {
|
| + history_service_->TopHosts(
|
| + NumTopHosts(),
|
| + base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr()));
|
| + } else {
|
| + InitializeAndStartFetcher();
|
| + }
|
| } else if (IsInControlGroup()) {
|
| - // Set is_precaching_ so that the longer delay is placed between calls to
|
| - // TopHosts.
|
| - is_precaching_ = true;
|
| -
|
| // Calculate TopHosts solely for metrics purposes.
|
| - history_service_->TopHosts(
|
| - NumTopHosts(),
|
| - base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr()));
|
| + if (needs_top_hosts) {
|
| + history_service_->TopHosts(
|
| + NumTopHosts(),
|
| + base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr()));
|
| + } else {
|
| + OnDone();
|
| + }
|
| } else {
|
| if (PrecachingAllowed() != AllowedType::PENDING) {
|
| // We are not waiting on the sync backend to be initialized. The user
|
| // either is not in the field trial, or does not have sync enabled.
|
| // Pretend that precaching started, so that the PrecacheServiceLauncher
|
| // doesn't try to start it again.
|
| - is_precaching_ = true;
|
| }
|
|
|
| OnDone();
|
| @@ -161,17 +185,26 @@ void PrecacheManager::StartPrecaching(
|
|
|
| void PrecacheManager::CancelPrecaching() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| if (!is_precaching_) {
|
| // Do nothing if precaching is not in progress.
|
| return;
|
| }
|
| is_precaching_ = false;
|
| -
|
| - // Destroying the |precache_fetcher_| will cancel any fetch in progress.
|
| - precache_fetcher_.reset();
|
| -
|
| - // Uninitialize the callback so that any scoped_refptrs in it are released.
|
| + // If cancellation occurs after StartPrecaching but before OnHostsReceived,
|
| + // is_precaching will be true, but the precache_fetcher_ will not yet be
|
| + // constructed.
|
| + if (precache_fetcher_) {
|
| + std::unique_ptr<PrecacheUnfinishedWork> unfinished_work =
|
| + precache_fetcher_->CancelPrecaching();
|
| + BrowserThread::PostTask(
|
| + BrowserThread::DB,
|
| + FROM_HERE,
|
| + base::Bind(&PrecacheDatabase::SaveUnfinishedWork,
|
| + precache_database_->GetWeakPtr(),
|
| + base::Passed(&unfinished_work)));
|
| + // Destroying the |precache_fetcher_| will cancel any fetch in progress.
|
| + precache_fetcher_.reset();
|
| + }
|
| precache_completion_callback_.Reset();
|
| }
|
|
|
| @@ -250,7 +283,6 @@ void PrecacheManager::Shutdown() {
|
|
|
| void PrecacheManager::OnDone() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| precache_fetcher_.reset();
|
|
|
| // Run completion callback if not null. It's null if the client is in the
|
| @@ -269,25 +301,27 @@ void PrecacheManager::OnHostsReceived(
|
| const history::TopHostsList& host_counts) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
|
| + std::vector<std::string> hosts;
|
| + for (const auto& host_count : host_counts)
|
| + unfinished_work_->add_top_host()->set_hostname(host_count.first);
|
| + InitializeAndStartFetcher();
|
| +}
|
| +
|
| +void PrecacheManager::InitializeAndStartFetcher() {
|
| if (!is_precaching_) {
|
| // Don't start precaching if it was canceled while waiting for the list of
|
| // hosts.
|
| return;
|
| }
|
| -
|
| - std::vector<std::string> hosts;
|
| - for (const auto& host_count : host_counts)
|
| - hosts.push_back(host_count.first);
|
| -
|
| // Start precaching.
|
| precache_fetcher_.reset(new PrecacheFetcher(
|
| - hosts,
|
| content::BrowserContext::GetDefaultStoragePartition(browser_context_)->
|
| GetURLRequestContext(),
|
| GURL(variations::GetVariationParamValue(
|
| kPrecacheFieldTrialName, kConfigURLParam)),
|
| variations::GetVariationParamValue(
|
| kPrecacheFieldTrialName, kManifestURLPrefixParam),
|
| + std::move(unfinished_work_),
|
| this));
|
| precache_fetcher_->Start();
|
| }
|
|
|