| Index: components/password_manager/core/browser/affiliation_backend.cc
|
| diff --git a/components/password_manager/core/browser/affiliation_backend.cc b/components/password_manager/core/browser/affiliation_backend.cc
|
| index ec937608af23d26e17d6fdf7bce07e4672aea742..5b2c637beb046053f8284ef0a4b124068d858a6d 100644
|
| --- a/components/password_manager/core/browser/affiliation_backend.cc
|
| +++ b/components/password_manager/core/browser/affiliation_backend.cc
|
| @@ -9,12 +9,12 @@
|
| #include "base/bind.h"
|
| #include "base/location.h"
|
| #include "base/single_thread_task_runner.h"
|
| -#include "base/task_runner.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| #include "base/threading/thread_checker.h"
|
| #include "base/time/clock.h"
|
| +#include "base/time/tick_clock.h"
|
| #include "base/time/time.h"
|
| #include "components/password_manager/core/browser/affiliation_database.h"
|
| +#include "components/password_manager/core/browser/affiliation_fetch_throttler.h"
|
| #include "components/password_manager/core/browser/affiliation_fetcher.h"
|
| #include "components/password_manager/core/browser/facet_manager.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| @@ -23,9 +23,13 @@ namespace password_manager {
|
|
|
| AffiliationBackend::AffiliationBackend(
|
| const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
|
| - scoped_ptr<base::Clock> time_source)
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| + scoped_ptr<base::Clock> time_source,
|
| + scoped_ptr<base::TickClock> time_tick_source)
|
| : request_context_getter_(request_context_getter),
|
| + task_runner_(task_runner),
|
| clock_(time_source.Pass()),
|
| + tick_clock_(time_tick_source.Pass()),
|
| weak_ptr_factory_(this) {
|
| DCHECK_LT(base::Time(), clock_->Now());
|
| }
|
| @@ -35,6 +39,11 @@ AffiliationBackend::~AffiliationBackend() {
|
|
|
| void AffiliationBackend::Initialize(const base::FilePath& db_path) {
|
| thread_checker_.reset(new base::ThreadChecker);
|
| +
|
| + DCHECK(!throttler_);
|
| + throttler_.reset(
|
| + new AffiliationFetchThrottler(this, task_runner_, tick_clock_.get()));
|
| +
|
| cache_.reset(new AffiliationDatabase());
|
| if (!cache_->Init(db_path)) {
|
| // TODO(engedy): Implement this. crbug.com/437865.
|
| @@ -99,20 +108,6 @@ FacetManager* AffiliationBackend::GetOrCreateFacetManager(
|
| return facet_managers_.get(facet_uri);
|
| }
|
|
|
| -void AffiliationBackend::SendNetworkRequest() {
|
| - DCHECK(!fetcher_);
|
| -
|
| - std::vector<FacetURI> requested_facet_uris;
|
| - for (const auto& facet_manager_pair : facet_managers_) {
|
| - if (facet_manager_pair.second->DoesRequireFetch())
|
| - requested_facet_uris.push_back(facet_manager_pair.first);
|
| - }
|
| - DCHECK(!requested_facet_uris.empty());
|
| - fetcher_.reset(AffiliationFetcher::Create(request_context_getter_.get(),
|
| - requested_facet_uris, this));
|
| - fetcher_->StartRequest();
|
| -}
|
| -
|
| void AffiliationBackend::OnSendNotification(const FacetURI& facet_uri) {
|
| DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
|
|
|
| @@ -132,17 +127,14 @@ bool AffiliationBackend::ReadAffiliationsFromDatabase(
|
| }
|
|
|
| void AffiliationBackend::SignalNeedNetworkRequest() {
|
| - // TODO(engedy): Add more sophisticated throttling logic. crbug.com/437865.
|
| - if (fetcher_)
|
| - return;
|
| - SendNetworkRequest();
|
| + throttler_->SignalNetworkRequestNeeded();
|
| }
|
|
|
| void AffiliationBackend::RequestNotificationAtTime(const FacetURI& facet_uri,
|
| base::Time time) {
|
| // TODO(engedy): Avoid spamming the task runner; only ever schedule the first
|
| // callback. crbug.com/437865.
|
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
| + task_runner_->PostDelayedTask(
|
| FROM_HERE, base::Bind(&AffiliationBackend::OnSendNotification,
|
| weak_ptr_factory_.GetWeakPtr(), facet_uri),
|
| time - clock_->Now());
|
| @@ -151,7 +143,9 @@ void AffiliationBackend::RequestNotificationAtTime(const FacetURI& facet_uri,
|
| void AffiliationBackend::OnFetchSucceeded(
|
| scoped_ptr<AffiliationFetcherDelegate::Result> result) {
|
| DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
|
| +
|
| fetcher_.reset();
|
| + throttler_->InformOfNetworkRequestComplete(true);
|
|
|
| for (const AffiliatedFacets& affiliated_facets : *result) {
|
| AffiliatedFacetsWithUpdateTime affiliation;
|
| @@ -182,7 +176,7 @@ void AffiliationBackend::OnFetchSucceeded(
|
| // requests came in while the current fetch was in flight.
|
| for (const auto& facet_manager_pair : facet_managers_) {
|
| if (facet_manager_pair.second->DoesRequireFetch()) {
|
| - SendNetworkRequest();
|
| + throttler_->SignalNetworkRequestNeeded();
|
| return;
|
| }
|
| }
|
| @@ -191,15 +185,46 @@ void AffiliationBackend::OnFetchSucceeded(
|
| void AffiliationBackend::OnFetchFailed() {
|
| DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
|
|
|
| - // TODO(engedy): Implement this. crbug.com/437865.
|
| - NOTIMPLEMENTED();
|
| + fetcher_.reset();
|
| + throttler_->InformOfNetworkRequestComplete(false);
|
| +
|
| + // Trigger a retry if a fetch is still needed.
|
| + for (const auto& facet_manager_pair : facet_managers_) {
|
| + if (facet_manager_pair.second->DoesRequireFetch()) {
|
| + throttler_->SignalNetworkRequestNeeded();
|
| + return;
|
| + }
|
| + }
|
| }
|
|
|
| void AffiliationBackend::OnMalformedResponse() {
|
| DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
|
|
|
| - // TODO(engedy): Implement this. crbug.com/437865.
|
| - NOTIMPLEMENTED();
|
| + // TODO(engedy): Potentially handle this case differently. crbug.com/437865.
|
| + OnFetchFailed();
|
| +}
|
| +
|
| +bool AffiliationBackend::OnCanSendNetworkRequest() {
|
| + DCHECK(!fetcher_);
|
| + std::vector<FacetURI> requested_facet_uris;
|
| + for (const auto& facet_manager_pair : facet_managers_) {
|
| + if (facet_manager_pair.second->DoesRequireFetch())
|
| + requested_facet_uris.push_back(facet_manager_pair.first);
|
| + }
|
| +
|
| + // In case a request is no longer needed, return false to indicate this.
|
| + if (requested_facet_uris.empty())
|
| + return false;
|
| +
|
| + fetcher_.reset(AffiliationFetcher::Create(request_context_getter_.get(),
|
| + requested_facet_uris, this));
|
| + fetcher_->StartRequest();
|
| + return true;
|
| +}
|
| +
|
| +void AffiliationBackend::SetThrottlerForTesting(
|
| + scoped_ptr<AffiliationFetchThrottler> throttler) {
|
| + throttler_ = throttler.Pass();
|
| }
|
|
|
| } // namespace password_manager
|
|
|