remove_uninstalled_apps_task.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chrome/updater/remove_uninstalled_apps_task.h"
  5. #include <string>
  6. #include <vector>
  7. #include "base/barrier_closure.h"
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/files/file_path.h"
  11. #include "base/files/file_util.h"
  12. #include "base/logging.h"
  13. #include "base/memory/scoped_refptr.h"
  14. #include "base/sequence_checker.h"
  15. #include "base/task/thread_pool.h"
  16. #include "base/threading/sequenced_task_runner_handle.h"
  17. #include "base/version.h"
  18. #include "chrome/updater/configurator.h"
  19. #include "chrome/updater/constants.h"
  20. #include "chrome/updater/persisted_data.h"
  21. #include "chrome/updater/prefs.h"
  22. #include "chrome/updater/update_service_impl.h"
  23. #include "chrome/updater/util.h"
  24. #include "components/prefs/pref_service.h"
  25. #include "components/update_client/update_client.h"
  26. #include "third_party/abseil-cpp/absl/types/optional.h"
  27. namespace updater {
  28. namespace {
  29. struct AppInfo {
  30. AppInfo(const std::string& app_id,
  31. const base::Version& app_version,
  32. const base::FilePath& ecp)
  33. : app_id_(app_id), app_version_(app_version), ecp_(ecp) {}
  34. std::string app_id_;
  35. base::Version app_version_;
  36. base::FilePath ecp_;
  37. };
  38. struct PingInfo {
  39. PingInfo(const std::string& app_id,
  40. const base::Version& app_version,
  41. int ping_reason)
  42. : app_id_(app_id), app_version_(app_version), ping_reason_(ping_reason) {}
  43. std::string app_id_;
  44. base::Version app_version_;
  45. int ping_reason_;
  46. };
  47. std::vector<AppInfo> GetRegisteredApps(
  48. scoped_refptr<updater::PersistedData> persisted_data) {
  49. std::vector<AppInfo> apps;
  50. for (const std::string& app_id : persisted_data->GetAppIds()) {
  51. if (app_id != kUpdaterAppId)
  52. apps.emplace_back(app_id, persisted_data->GetProductVersion(app_id),
  53. persisted_data->GetExistenceCheckerPath(app_id));
  54. }
  55. return apps;
  56. }
  57. std::vector<PingInfo> GetAppIDsToRemove(
  58. const std::vector<AppInfo>& apps,
  59. base::RepeatingCallback<absl::optional<int>(const std::string&,
  60. const base::FilePath&)>
  61. predicate) {
  62. std::vector<PingInfo> app_ids_to_remove;
  63. for (const auto& app : apps) {
  64. absl::optional<int> remove_reason = predicate.Run(app.app_id_, app.ecp_);
  65. if (remove_reason) {
  66. app_ids_to_remove.emplace_back(app.app_id_, app.app_version_,
  67. *remove_reason);
  68. }
  69. }
  70. return app_ids_to_remove;
  71. }
  72. void UninstallPingSent(base::RepeatingClosure callback,
  73. update_client::Error error) {
  74. if (error != update_client::Error::NONE)
  75. VLOG(0) << __func__ << ": Error: " << static_cast<int>(error);
  76. callback.Run();
  77. }
  78. void RemoveAppIDsAndSendUninstallPings(
  79. base::OnceClosure callback,
  80. scoped_refptr<PersistedData> persisted_data,
  81. scoped_refptr<update_client::UpdateClient> update_client,
  82. const std::vector<PingInfo>& app_ids_to_remove) {
  83. if (app_ids_to_remove.empty()) {
  84. std::move(callback).Run();
  85. return;
  86. }
  87. const auto barrier_closure =
  88. base::BarrierClosure(app_ids_to_remove.size(), std::move(callback));
  89. for (const PingInfo& app_id_to_remove : app_ids_to_remove) {
  90. const std::string& app_id = app_id_to_remove.app_id_;
  91. const int ping_reason = app_id_to_remove.ping_reason_;
  92. const base::Version& app_version = app_id_to_remove.app_version_;
  93. const std::string& brand = persisted_data->GetBrandCode(app_id);
  94. const std::string& ap = persisted_data->GetAP(app_id);
  95. if (persisted_data->RemoveApp(app_id)) {
  96. VLOG(1) << "Uninstall ping for app id: " << app_id
  97. << ". Ping reason: " << ping_reason;
  98. update_client::CrxComponent crx_component;
  99. crx_component.ap = ap;
  100. crx_component.app_id = app_id;
  101. crx_component.brand = brand;
  102. crx_component.version = app_version;
  103. crx_component.requires_network_encryption = false;
  104. update_client->SendUninstallPing(
  105. crx_component, ping_reason,
  106. base::BindOnce(&UninstallPingSent, barrier_closure));
  107. } else {
  108. VLOG(0) << "Could not remove registration of app " << app_id;
  109. }
  110. }
  111. }
  112. } // namespace
  113. RemoveUninstalledAppsTask::RemoveUninstalledAppsTask(
  114. scoped_refptr<Configurator> config,
  115. UpdaterScope scope)
  116. : config_(config),
  117. persisted_data_(
  118. base::MakeRefCounted<PersistedData>(config_->GetPrefService())),
  119. update_client_(update_client::UpdateClientFactory(config_)),
  120. scope_(scope) {}
  121. RemoveUninstalledAppsTask::~RemoveUninstalledAppsTask() = default;
  122. void RemoveUninstalledAppsTask::Run(base::OnceClosure callback) {
  123. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  124. base::ThreadPool::PostTaskAndReplyWithResult(
  125. FROM_HERE, {base::MayBlock()},
  126. base::BindOnce(
  127. GetAppIDsToRemove, GetRegisteredApps(persisted_data_),
  128. base::BindRepeating(&RemoveUninstalledAppsTask::GetUnregisterReason,
  129. this)),
  130. base::BindOnce(&RemoveAppIDsAndSendUninstallPings, std::move(callback),
  131. persisted_data_, update_client_));
  132. }
  133. } // namespace updater