blob: 11aaeba3b64b29cce90f54290d50732fbe653fa7 [file] [log] [blame]
// Copyright 2020 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.
#include "chrome/updater/control_service_impl.h"
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/threading/sequenced_task_runner_handle.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/prefs.h"
#include "chrome/updater/update_service_impl.h"
#include "components/prefs/pref_service.h"
namespace updater {
ControlServiceImpl::ControlServiceImpl(
scoped_refptr<updater::Configurator> config)
: config_(config),
persisted_data_(
base::MakeRefCounted<PersistedData>(config_->GetPrefService())) {}
void ControlServiceImpl::Run(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
UnregisterMissingApps();
MaybeCheckForUpdates(std::move(callback));
}
void ControlServiceImpl::InitializeUpdateService(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__;
std::move(callback).Run();
}
void ControlServiceImpl::MaybeCheckForUpdates(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const base::Time lastUpdateTime =
config_->GetPrefService()->GetTime(kPrefUpdateTime);
const base::TimeDelta timeSinceUpdate =
base::Time::NowFromSystemTime() - lastUpdateTime;
if (base::TimeDelta() < timeSinceUpdate &&
timeSinceUpdate <
base::TimeDelta::FromSeconds(config_->NextCheckDelay())) {
VLOG(0) << "Skipping checking for updates: "
<< timeSinceUpdate.InMinutes();
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
return;
}
scoped_refptr<UpdateServiceImpl> update_service =
base::MakeRefCounted<UpdateServiceImpl>(config_);
update_service->UpdateAll(
base::DoNothing(),
base::BindOnce(
[](base::OnceClosure closure,
scoped_refptr<updater::Configurator> config,
UpdateService::Result result) {
const int exit_code = static_cast<int>(result);
VLOG(0) << "UpdateAll complete: exit_code = " << exit_code;
if (result == UpdateService::Result::kSuccess) {
config->GetPrefService()->SetTime(
kPrefUpdateTime, base::Time::NowFromSystemTime());
}
std::move(closure).Run();
},
base::BindOnce(std::move(callback)), config_));
}
void ControlServiceImpl::UnregisterMissingApps() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
for (const auto& app_id : persisted_data_->GetAppIds()) {
// Skip if app_id is equal to updater app id.
if (app_id == kUpdaterAppId)
continue;
const base::FilePath ecp = persisted_data_->GetExistenceCheckerPath(app_id);
if (!ecp.empty() && !base::PathExists(ecp)) {
if (!persisted_data_->RemoveApp(app_id))
VLOG(0) << "Could not remove registration of app " << app_id;
}
}
}
void ControlServiceImpl::Uninitialize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
PrefsCommitPendingWrites(config_->GetPrefService());
}
ControlServiceImpl::~ControlServiceImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
config_->GetPrefService()->SchedulePendingLossyWrites();
}
} // namespace updater