1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/updater/check_for_updates_task.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/rand_util.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/policy/manager.h"
#include "chrome/updater/policy/service.h"
#include "chrome/updater/update_service_impl.h"
#include "chrome/updater/updater_scope.h"
#include "chrome/updater/util/util.h"
#include "components/prefs/pref_service.h"
#include "components/update_client/update_client.h"
namespace updater {
namespace {
bool ShouldSkipCheck(scoped_refptr<Configurator> config,
const std::string& task_name) {
// To spread out synchronized load, sometimes use a higher delay.
const base::TimeDelta check_delay =
config->NextCheckDelay() * (base::RandDouble() < 0.1 ? 1.2 : 1);
// Skip if periodic updates are disabled altogether, for instance, by an admin
// setting `AutoUpdateCheckPeriodMinutes` to zero.
if (check_delay.is_zero()) {
VLOG(0) << "Skipping " << task_name << ": NextCheckDelay is 0.";
return true;
}
// Skip if the most recent check was too recent (and not in the future).
const base::TimeDelta time_since_update =
base::Time::NowFromSystemTime() -
config->GetUpdaterPersistedData()->GetLastChecked();
if (time_since_update.is_positive() && time_since_update < check_delay) {
VLOG(0) << "Skipping " << task_name << ": last update was "
<< time_since_update.InMinutes()
<< " minutes ago. check_delay == " << check_delay.InMinutes();
return true;
}
// Skip if the updater is in the update suppression period.
return config->GetPolicyService()->AreUpdatesSuppressedNow();
}
} // namespace
CheckForUpdatesTask::CheckForUpdatesTask(scoped_refptr<Configurator> config,
UpdaterScope scope,
const std::string& task_name,
UpdateChecker update_checker)
: config_(config),
task_name_(task_name),
update_checker_(std::move(update_checker)),
update_client_(update_client::UpdateClientFactory(config_)) {}
CheckForUpdatesTask::~CheckForUpdatesTask() = default;
void CheckForUpdatesTask::Run(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (ShouldSkipCheck(config_, task_name_)) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, std::move(callback));
return;
}
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(
std::move(update_checker_),
base::BindOnce(
[](base::OnceClosure closure, const std::string& task_name,
UpdateService::Result result) {
VLOG(0) << task_name << " task complete: " << result;
std::move(closure).Run();
},
std::move(callback), task_name_)));
}
} // namespace updater
|