blob: 6f0d56f485cba8a158a41f5781ac70ade2bd1036 [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/app/app_server.h"
#include <memory>
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/version.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.h"
#include "chrome/updater/update_service_impl.h"
#include "chrome/updater/update_service_impl_inactive.h"
#include "chrome/updater/update_service_internal.h"
#include "chrome/updater/update_service_internal_impl.h"
#include "chrome/updater/update_service_internal_impl_inactive.h"
#include "chrome/updater/updater_version.h"
#include "components/prefs/pref_service.h"
namespace updater {
AppServer::AppServer() = default;
AppServer::~AppServer() = default;
void AppServer::Initialize() {
first_task_ = ModeCheck();
}
base::OnceClosure AppServer::ModeCheck() {
std::unique_ptr<GlobalPrefs> global_prefs = CreateGlobalPrefs();
if (!global_prefs) {
return base::BindOnce(&AppServer::Shutdown, this,
kErrorFailedToLockPrefsMutex);
}
const base::Version this_version(UPDATER_VERSION_STRING);
const base::Version active_version(global_prefs->GetActiveVersion());
VLOG(2) << "This version: " << this_version.GetString()
<< ", active version: " << active_version.GetString();
if (this_version < active_version) {
global_prefs = nullptr;
uninstall_ = true;
return base::BindOnce(&AppServer::ActiveDuty, this,
MakeInactiveUpdateService(),
MakeInactiveUpdateServiceInternal());
}
if (active_version != base::Version("0") && active_version != this_version) {
std::unique_ptr<LocalPrefs> local_prefs = CreateLocalPrefs();
if (!local_prefs->GetQualified()) {
global_prefs = nullptr;
return base::BindOnce(&AppServer::Qualify, this, std::move(local_prefs));
}
}
if (this_version > active_version || global_prefs->GetSwapping()) {
if (!SwapVersions(global_prefs.get()))
return base::BindOnce(&AppServer::Shutdown, this, kErrorFailedToSwap);
}
config_ = base::MakeRefCounted<Configurator>(std::move(global_prefs));
return base::BindOnce(
&AppServer::ActiveDuty, this,
base::MakeRefCounted<UpdateServiceImpl>(config_),
base::MakeRefCounted<UpdateServiceInternalImpl>(config_));
}
void AppServer::Uninitialize() {
if (config_)
PrefsCommitPendingWrites(config_->GetPrefService());
if (uninstall_) {
VLOG(1) << "Uninstalling version " << UPDATER_VERSION_STRING;
UninstallSelf();
}
}
void AppServer::FirstTaskRun() {
std::move(first_task_).Run();
}
void AppServer::Qualify(std::unique_ptr<LocalPrefs> local_prefs) {
// For now, assume qualification succeeds.
DVLOG(2) << __func__;
local_prefs->SetQualified(true);
PrefsCommitPendingWrites(local_prefs->GetPrefService());
// Start ActiveDuty with inactive service implementations. To use active
// implementations, the server would have to ModeCheck again.
ActiveDuty(MakeInactiveUpdateService(), MakeInactiveUpdateServiceInternal());
}
bool AppServer::SwapVersions(GlobalPrefs* global_prefs) {
global_prefs->SetSwapping(true);
PrefsCommitPendingWrites(global_prefs->GetPrefService());
bool result = SwapRPCInterfaces();
if (!result)
return false;
global_prefs->SetActiveVersion(UPDATER_VERSION_STRING);
scoped_refptr<PersistedData> persisted_data =
base::MakeRefCounted<PersistedData>(global_prefs->GetPrefService());
if (!persisted_data->GetProductVersion(kUpdaterAppId).IsValid()) {
persisted_data->SetProductVersion(kUpdaterAppId,
base::Version(UPDATER_VERSION_STRING));
}
global_prefs->SetSwapping(false);
PrefsCommitPendingWrites(global_prefs->GetPrefService());
return true;
}
} // namespace updater