blob: 0687e26a3d3a8966608af60fd53174409f043dcc [file] [log] [blame]
// Copyright 2022 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/auto_run_on_os_upgrade_task.h"
#include <algorithm>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/process/launch.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/thread_pool.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/util.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "chrome/updater/win/app_command_runner.h"
#include "chrome/updater/win/win_constants.h"
#include "chrome/updater/win/win_util.h"
#endif
namespace updater {
AutoRunOnOsUpgradeTask::AutoRunOnOsUpgradeTask(
UpdaterScope scope,
scoped_refptr<PersistedData> persisted_data)
: scope_(scope), persisted_data_(persisted_data) {}
AutoRunOnOsUpgradeTask::~AutoRunOnOsUpgradeTask() = default;
void AutoRunOnOsUpgradeTask::Run(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!HasOSUpgraded()) {
std::move(callback).Run();
return;
}
base::ThreadPool::PostTaskAndReply(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&AutoRunOnOsUpgradeTask::RunOnOsUpgradeForApps, this,
persisted_data_->GetAppIds()),
base::BindOnce(&AutoRunOnOsUpgradeTask::SetOSUpgraded, this)
.Then(std::move(callback)));
}
void AutoRunOnOsUpgradeTask::RunOnOsUpgradeForApps(
const std::vector<std::string>& app_ids) {
std::for_each(app_ids.begin(), app_ids.end(),
[&](const auto& app_id) { RunOnOsUpgradeForApp(app_id); });
}
#if BUILDFLAG(IS_WIN)
size_t AutoRunOnOsUpgradeTask::RunOnOsUpgradeForApp(const std::string& app_id) {
size_t number_of_successful_tasks = 0;
const std::vector<AppCommandRunner> app_command_runners =
AppCommandRunner::LoadAutoRunOnOsUpgradeAppCommands(
scope_, base::SysUTF8ToWide(app_id));
std::for_each(app_command_runners.begin(), app_command_runners.end(),
[&](const auto& app_command_runner) {
base::Process process;
if (FAILED(app_command_runner.Run({}, process)))
return;
VLOG(1) << "Successfully launched OS upgrade task with PID: "
<< process.Pid();
++number_of_successful_tasks;
});
return number_of_successful_tasks;
}
bool AutoRunOnOsUpgradeTask::HasOSUpgraded() {
const absl::optional<OSVERSIONINFOEX> last_os_version =
persisted_data_->GetLastOSVersion();
if (!last_os_version) {
// Initialize the OS version.
persisted_data_->SetLastOSVersion();
return false;
}
return CompareOSVersions(last_os_version.value(), VER_GREATER);
}
void AutoRunOnOsUpgradeTask::SetOSUpgraded() {
// Save the current OS as the old OS version.
persisted_data_->SetLastOSVersion();
}
#else // BUILDFLAG(IS_WIN)
size_t AutoRunOnOsUpgradeTask::RunOnOsUpgradeForApp(const std::string& app_id) {
return 0;
}
bool AutoRunOnOsUpgradeTask::HasOSUpgraded() {
return false;
}
void AutoRunOnOsUpgradeTask::SetOSUpgraded() {}
#endif // BUILDFLAG(IS_WIN)
} // namespace updater