| Index: components/update_client/update_engine.cc
|
| diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc
|
| index 06cf6eb723d7f921f0427890935e00651baa9204..20f9a6acf1e28f30be484fe7548aff4527dc37f9 100644
|
| --- a/components/update_client/update_engine.cc
|
| +++ b/components/update_client/update_engine.cc
|
| @@ -9,6 +9,7 @@
|
| #include "base/location.h"
|
| #include "base/stl_util.h"
|
| #include "base/thread_task_runner_handle.h"
|
| +#include "base/time/time.h"
|
| #include "components/update_client/action_update_check.h"
|
| #include "components/update_client/configurator.h"
|
| #include "components/update_client/crx_update_item.h"
|
| @@ -36,8 +37,8 @@ UpdateContext::UpdateContext(
|
| blocking_task_runner(config->GetSequencedTaskRunner()),
|
| update_checker_factory(update_checker_factory),
|
| crx_downloader_factory(crx_downloader_factory),
|
| - ping_manager(ping_manager) {
|
| -}
|
| + ping_manager(ping_manager),
|
| + retry_after_sec_(0) {}
|
|
|
| UpdateContext::~UpdateContext() {
|
| STLDeleteElements(&update_items);
|
| @@ -84,6 +85,12 @@ void UpdateEngine::Update(
|
| const CompletionCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| + if (IsThrottled(is_foreground)) {
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(callback, Error::ERROR_UPDATE_RETRY_LATER));
|
| + return;
|
| + }
|
| +
|
| scoped_ptr<UpdateContext> update_context(new UpdateContext(
|
| config_, is_foreground, ids, crx_data_callback,
|
| notify_observers_callback_, callback, update_checker_factory_,
|
| @@ -109,6 +116,18 @@ void UpdateEngine::UpdateComplete(UpdateContext* update_context, int error) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(update_contexts_.find(update_context) != update_contexts_.end());
|
|
|
| + const int throttle_sec(update_context->retry_after_sec_);
|
| + DCHECK_LE(throttle_sec, 24 * 60 * 60);
|
| +
|
| + // Only positive values for throttle_sec are effective. 0 means that no
|
| + // throttling occurs and has the effect of resetting the member.
|
| + // Negative values are not trusted and are ignored.
|
| + if (throttle_sec >= 0)
|
| + throttle_updates_until_ =
|
| + throttle_sec
|
| + ? base::Time::Now() + base::TimeDelta::FromSeconds(throttle_sec)
|
| + : base::Time();
|
| +
|
| auto callback = update_context->callback;
|
|
|
| update_contexts_.erase(update_context);
|
| @@ -117,4 +136,16 @@ void UpdateEngine::UpdateComplete(UpdateContext* update_context, int error) {
|
| callback.Run(error);
|
| }
|
|
|
| +bool UpdateEngine::IsThrottled(bool is_foreground) const {
|
| + if (is_foreground || throttle_updates_until_.is_null())
|
| + return false;
|
| +
|
| + const auto now(base::Time::Now());
|
| +
|
| + // Throttle the calls in the interval (t - 1 day, t) to limit the effect of
|
| + // unset clocks or clock drift.
|
| + return throttle_updates_until_ - base::TimeDelta::FromDays(1) < now &&
|
| + now < throttle_updates_until_;
|
| +}
|
| +
|
| } // namespace update_client
|
|
|