blob: 339ed8aae2572713a2439473718915934da19983 [file] [log] [blame]
// Copyright 2021 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/browser/safe_browsing/chrome_user_population_helper.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/content/browser/user_population.h"
#include "components/sync/driver/sync_service.h"
namespace safe_browsing {
namespace {
absl::optional<ChromeUserPopulation>& GetCachedUserPopulation(
Profile* profile) {
static base::NoDestructor<
std::map<Profile*, absl::optional<ChromeUserPopulation>>>
instance;
return (*instance)[profile];
}
NoCachedPopulationReason& GetNoCachedPopulationReason(Profile* profile) {
static base::NoDestructor<std::map<Profile*, NoCachedPopulationReason>>
instance;
auto it = instance->find(profile);
if (it == instance->end()) {
(*instance)[profile] = NoCachedPopulationReason::kStartup;
}
return (*instance)[profile];
}
void ComparePopulationWithCache(Profile* profile,
const ChromeUserPopulation& population) {
const absl::optional<ChromeUserPopulation>& cached_population =
GetCachedUserPopulation(profile);
if (!cached_population) {
base::UmaHistogramEnumeration("SafeBrowsing.NoCachedPopulationReason",
GetNoCachedPopulationReason(profile));
return;
}
base::UmaHistogramBoolean(
"SafeBrowsing.PopulationMatchesCachedValue.Population",
cached_population->user_population() == population.user_population());
base::UmaHistogramBoolean(
"SafeBrowsing.PopulationMatchesCachedValue.UserAgent",
cached_population->user_agent() == population.user_agent());
base::UmaHistogramBoolean(
"SafeBrowsing.PopulationMatchesCachedValue.Mbb",
cached_population->is_mbb_enabled() == population.is_mbb_enabled());
}
} // namespace
void ClearCachedUserPopulation(Profile* profile,
NoCachedPopulationReason reason) {
GetCachedUserPopulation(profile) = absl::nullopt;
GetNoCachedPopulationReason(profile) = reason;
}
ChromeUserPopulation GetUserPopulationForProfile(Profile* profile) {
// |profile| may be null in tests.
if (!profile)
return ChromeUserPopulation();
syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile);
bool is_history_sync_enabled =
sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled() &&
sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
bool is_under_advanced_protection = false;
#if BUILDFLAG(FULL_SAFE_BROWSING)
AdvancedProtectionStatusManager* advanced_protection_manager =
AdvancedProtectionStatusManagerFactory::GetForProfile(profile);
is_under_advanced_protection =
advanced_protection_manager &&
advanced_protection_manager->IsUnderAdvancedProtection();
#endif
absl::optional<size_t> num_profiles;
absl::optional<size_t> num_loaded_profiles;
absl::optional<size_t> num_open_profiles;
ProfileManager* profile_manager = g_browser_process->profile_manager();
// |profile_manager| may be null in tests.
if (profile_manager) {
num_profiles = profile_manager->GetNumberOfProfiles();
num_loaded_profiles = profile_manager->GetLoadedProfiles().size();
// On ChromeOS multiple profiles doesn't apply, and GetLastOpenedProfiles
// causes
// crashes on ChromeOS. See https://crbug.com/1211793.
#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
num_open_profiles = profile_manager->GetLastOpenedProfiles().size();
#endif
}
ChromeUserPopulation population = GetUserPopulation(
profile->GetPrefs(), profile->IsOffTheRecord(), is_history_sync_enabled,
is_under_advanced_protection,
g_browser_process->browser_policy_connector(), std::move(num_profiles),
std::move(num_loaded_profiles), std::move(num_open_profiles));
ComparePopulationWithCache(profile, population);
GetCachedUserPopulation(profile) = population;
return population;
}
} // namespace safe_browsing