blob: 826cf6d100d4c740c17c855fb6e6931c6a920857 [file] [log] [blame]
// Copyright 2024 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/browser/profiles/profile_metrics.h"
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/strings/to_string.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_init_params.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/gaia/gaia_id.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
struct ProfileConfig {
std::u16string gaia_name;
bool active = true;
bool sync_consent = false;
bool supervised = false;
bool managed = false;
};
struct ProfileMetricsParam {
std::vector<ProfileConfig> profiles;
int expected_managed_profile_count = 0;
int expected_sync_consent_profile_count = 0;
int expected_active_profile_count = 0;
std::vector<base::Bucket> expected_name_share_samples;
};
const ProfileMetricsParam profile_metrics_test_params[] = {
// Single signed out active profile
{.profiles = {ProfileConfig()}, .expected_active_profile_count = 1},
// Inactive profile.
{.profiles = {{.active = false}}},
// Supervised profile.
{.profiles = {{.supervised = true}},
.expected_managed_profile_count = 1,
.expected_active_profile_count = 1},
// Syncing in profile.
{.profiles = {{.sync_consent = true}},
.expected_sync_consent_profile_count = 1,
.expected_active_profile_count = 1},
// With Gaia name.
{.profiles = {{.gaia_name = u"FirstName"}},
.expected_active_profile_count = 1,
.expected_name_share_samples = {base::Bucket(
ProfileMetrics::GaiaNameShareStatus::kNotShared,
1)}},
// Multiple profiles with various states.
{.profiles = {{.active = false},
{.sync_consent = true, .supervised = true},
{.gaia_name = u"Name1", .active = false},
{.gaia_name = u"Name2"}},
.expected_managed_profile_count = 1,
.expected_sync_consent_profile_count = 1,
.expected_active_profile_count = 2,
.expected_name_share_samples = {base::Bucket(
ProfileMetrics::GaiaNameShareStatus::kNotShared,
2)}},
// Duplicate Gaia name (non-managed).
{.profiles = {{.gaia_name = u"Name"}, {.gaia_name = u"Name"}},
.expected_active_profile_count = 2,
.expected_name_share_samples = {base::Bucket(
ProfileMetrics::GaiaNameShareStatus::kSharedNonManaged,
1)}},
// Duplicate Gaia name (managed).
{.profiles = {{.gaia_name = u"Name"},
{.gaia_name = u"Name", .managed = true}},
.expected_active_profile_count = 2,
.expected_name_share_samples = {base::Bucket(
ProfileMetrics::GaiaNameShareStatus::kSharedManaged,
1)}},
// Duplicate Gaia name: non-managed takes priority over managed.
{.profiles = {{.gaia_name = u"Name"},
{.gaia_name = u"Name"},
{.gaia_name = u"Name", .managed = true}},
.expected_active_profile_count = 3,
.expected_name_share_samples = {base::Bucket(
ProfileMetrics::GaiaNameShareStatus::kSharedNonManaged,
1)}},
// Multiple names with mixed sharing status.
{.profiles = {{ProfileConfig()},
{.gaia_name = u"Name1"},
{.gaia_name = u"Name1"},
{.gaia_name = u"Name2", .managed = true},
{.gaia_name = u"Name3"},
{.gaia_name = u"Name2", .managed = true},
{.gaia_name = u"Name4"},
{.gaia_name = u"Name1"}},
.expected_active_profile_count = 8,
.expected_name_share_samples =
{base::Bucket(ProfileMetrics::GaiaNameShareStatus::kNotShared, 2),
base::Bucket(ProfileMetrics::GaiaNameShareStatus::kSharedNonManaged,
1),
base::Bucket(ProfileMetrics::GaiaNameShareStatus::kSharedManaged,
1)}},
};
} // namespace
class ProfileMetricsTest : public testing::TestWithParam<ProfileMetricsParam> {
public:
void CheckProfileCountHistogram(const base::HistogramTester& histogram_tester,
const char* histogram,
int expected_count) {
histogram_tester.ExpectUniqueSample(histogram, expected_count, 1);
}
protected:
content::BrowserTaskEnvironment task_environment_;
TestingPrefServiceSimple prefs_;
};
TEST_P(ProfileMetricsTest, LogNumberOfProfiles) {
ProfileAttributesStorage::RegisterPrefs(prefs_.registry());
const ProfileMetricsParam test_param = GetParam();
base::FilePath user_data_dir = base::FilePath(FILE_PATH_LITERAL("/Foo"));
ProfileAttributesStorage storage(&prefs_, user_data_dir);
int i = 0;
for (const ProfileConfig& profile_config : test_param.profiles) {
ProfileAttributesInitParams profile_init_params;
base::FilePath profile_path = user_data_dir.AppendASCII(base::ToString(i));
profile_init_params.profile_path = profile_path;
profile_init_params.profile_name = u"profile name";
storage.AddProfile(std::move(profile_init_params));
ProfileAttributesEntry* entry =
storage.GetProfileAttributesWithPath(profile_path);
CHECK(entry);
entry->SetGAIAGivenName(profile_config.gaia_name);
if (profile_config.active) {
entry->SetActiveTimeToNow();
}
if (profile_config.supervised) {
entry->SetSupervisedUserId("supervised id");
}
if (profile_config.sync_consent) {
entry->SetAuthInfo(GaiaId("gaia"), u"email", true);
}
entry->SetUserAcceptedAccountManagement(profile_config.managed);
++i;
}
base::HistogramTester histogram_tester;
ProfileMetrics::LogNumberOfProfiles(&storage);
EXPECT_THAT(histogram_tester.GetAllSamples("Profile.GaiaNameShareStatus"),
base::BucketsAre(test_param.expected_name_share_samples));
histogram_tester.ExpectUniqueSample("Profile.NumberOfProfiles",
test_param.profiles.size(), 1);
histogram_tester.ExpectUniqueSample(
"Profile.NumberOfSignedInProfiles",
test_param.expected_sync_consent_profile_count, 1);
histogram_tester.ExpectUniqueSample("Profile.NumberOfManagedProfiles",
test_param.expected_managed_profile_count,
1);
#if BUILDFLAG(IS_ANDROID)
// All profiles are considered active on Android.
histogram_tester.ExpectUniqueSample("Profile.NumberOfActiveProfiles",
test_param.profiles.size(), 1);
histogram_tester.ExpectUniqueSample("Profile.NumberOfUnusedProfiles", 0, 1);
#else
histogram_tester.ExpectUniqueSample("Profile.NumberOfActiveProfiles",
test_param.expected_active_profile_count,
1);
histogram_tester.ExpectUniqueSample(
"Profile.NumberOfUnusedProfiles",
test_param.profiles.size() - test_param.expected_active_profile_count, 1);
#endif // BUILDFLAG(IS_ANDROID)
}
INSTANTIATE_TEST_SUITE_P(,
ProfileMetricsTest,
testing::ValuesIn(profile_metrics_test_params));