| // 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 |