| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/updater/update_usage_stats_task.h" |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/apple/foundation_util.h" |
| #include "base/files/file_enumerator.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "chrome/updater/updater_branding.h" |
| #include "chrome/updater/updater_scope.h" |
| #include "chrome/updater/util/mac_util.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "third_party/crashpad/crashpad/client/crash_report_database.h" |
| #include "third_party/crashpad/crashpad/client/settings.h" |
| |
| namespace updater { |
| |
| namespace { |
| |
| bool OtherAppUsageStatsAllowedInDir(const base::FilePath& base_dir) { |
| base::FileEnumerator files( |
| base_dir.Append(FILE_PATH_LITERAL(COMPANY_SHORTNAME_STRING)), false, |
| base::FileEnumerator::FileType::DIRECTORIES); |
| for (base::FilePath name = files.Next(); !name.empty(); name = files.Next()) { |
| if (name.BaseName().value() == PRODUCT_FULLNAME_STRING) { |
| continue; |
| } |
| base::FilePath crashpad = name.AppendASCII("Crashpad"); |
| if (base::PathExists(crashpad)) { |
| std::unique_ptr<crashpad::CrashReportDatabase> app_database = |
| crashpad::CrashReportDatabase::Initialize(crashpad); |
| if (!app_database) |
| continue; |
| crashpad::Settings* app_settings = app_database->GetSettings(); |
| bool enabled = false; |
| if (app_settings->GetUploadsEnabled(&enabled) && enabled) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| } // namespace |
| |
| // Returns whether any crashpad databases in ~/Library/Application |
| // Support/<company name>/<app name>/Crashpad have upload enabled. Google |
| // Chrome channels all follow this pattern. |
| bool OtherAppUsageStatsAllowed(const std::vector<std::string>& app_ids, |
| UpdaterScope scope) { |
| if (!IsSystemInstall(scope)) { |
| absl::optional<base::FilePath> application_support_dir = |
| GetApplicationSupportDirectory(UpdaterScope::kUser); |
| return application_support_dir && |
| OtherAppUsageStatsAllowedInDir(*application_support_dir); |
| } |
| // In the system case, iterate all users. If any user has opted-in to usage |
| // stats, the system updater may transmit usage stats. |
| base::FilePath user_dir; |
| if (!base::apple::GetLocalDirectory(NSUserDirectory, &user_dir)) { |
| return false; |
| } |
| base::FileEnumerator files(user_dir, false, |
| base::FileEnumerator::FileType::DIRECTORIES); |
| for (base::FilePath name = files.Next(); !name.empty(); name = files.Next()) { |
| if (OtherAppUsageStatsAllowedInDir( |
| name.Append(FILE_PATH_LITERAL("Library")) |
| .Append(FILE_PATH_LITERAL("Application Support")))) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } // namespace updater |