diff --git a/browser/brave_browser_features.cc b/browser/brave_browser_features.cc index 136d8bb049f..0d3d2c5b6f8 100644 --- a/browser/brave_browser_features.cc +++ b/browser/brave_browser_features.cc @@ -4,6 +4,7 @@ * You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "brave/browser/brave_browser_features.h" + #include "build/build_config.h" namespace features { @@ -41,4 +42,10 @@ BASE_FEATURE(kBraveDayZeroExperiment, "BraveDayZeroExperiment", base::FEATURE_DISABLED_BY_DEFAULT); +// The variant of the "day zero" experiment. i.e. A, B, C, D, etc. +const base::FeatureParam kBraveDayZeroExperimentVariant{ + &kBraveDayZeroExperiment, + /*name=*/"variant", + /*default_value=*/""}; + } // namespace features diff --git a/browser/brave_browser_features.h b/browser/brave_browser_features.h index fef6b6587ea..a3b4a9a9365 100644 --- a/browser/brave_browser_features.h +++ b/browser/brave_browser_features.h @@ -6,7 +6,10 @@ #ifndef BRAVE_BROWSER_BRAVE_BROWSER_FEATURES_H_ #define BRAVE_BROWSER_BRAVE_BROWSER_FEATURES_H_ +#include + #include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" namespace features { @@ -14,7 +17,9 @@ BASE_DECLARE_FEATURE(kBraveCleanupSessionCookiesOnSessionRestore); BASE_DECLARE_FEATURE(kBraveCopyCleanLinkByDefault); BASE_DECLARE_FEATURE(kBraveOverrideDownloadDangerLevel); BASE_DECLARE_FEATURE(kBraveWebViewRoundedCorners); + BASE_DECLARE_FEATURE(kBraveDayZeroExperiment); +extern const base::FeatureParam kBraveDayZeroExperimentVariant; } // namespace features diff --git a/browser/brave_stats/brave_stats_updater.cc b/browser/brave_stats/brave_stats_updater.cc index 0f826ca1d04..a1d5b94d6da 100644 --- a/browser/brave_stats/brave_stats_updater.cc +++ b/browser/brave_stats/brave_stats_updater.cc @@ -109,11 +109,14 @@ BraveStatsUpdater::BraveStatsUpdater(PrefService* pref_service, usage_server_ = BUILDFLAG(BRAVE_USAGE_SERVER); } + std::optional day_zero_variant; + if (base::FeatureList::IsEnabled(features::kBraveDayZeroExperiment)) { + day_zero_variant = features::kBraveDayZeroExperimentVariant.Get(); + } general_browser_usage_p3a_ = std::make_unique( - pref_service, - base::FeatureList::IsEnabled(features::kBraveDayZeroExperiment), - first_run::IsChromeFirstRun(), GetFirstRunTime(pref_service)); + pref_service, day_zero_variant, first_run::IsChromeFirstRun(), + GetFirstRunTime(pref_service)); if (profile_manager != nullptr) { g_browser_process->profile_manager()->AddObserver(this); diff --git a/components/misc_metrics/general_browser_usage.cc b/components/misc_metrics/general_browser_usage.cc index dc024058dac..3e696eee425 100644 --- a/components/misc_metrics/general_browser_usage.cc +++ b/components/misc_metrics/general_browser_usage.cc @@ -6,6 +6,8 @@ #include "brave/components/misc_metrics/general_browser_usage.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" #include "base/time/time.h" #include "brave/components/misc_metrics/pref_names.h" #include "brave/components/p3a_utils/bucket.h" @@ -25,17 +27,19 @@ constexpr int kProfileCountBuckets[] = {0, 1, 2, 3, 5}; } // namespace -GeneralBrowserUsage::GeneralBrowserUsage(PrefService* local_state, - bool day_zero_experiment_enabled, - bool is_first_run, - base::Time first_run_time) +GeneralBrowserUsage::GeneralBrowserUsage( + PrefService* local_state, + std::optional day_zero_experiment_variant, + bool is_first_run, + base::Time first_run_time) : local_state_(local_state), first_run_time_(first_run_time) { usage_storage_ = std::make_unique( local_state, kMiscMetricsBrowserUsageList); if (is_first_run) { - if (day_zero_experiment_enabled) { - local_state->SetBoolean(kMiscMetricsDayZeroAtInstall, true); + if (day_zero_experiment_variant) { + local_state->SetString(kMiscMetricsDayZeroVariantAtInstall, + *day_zero_experiment_variant); } if (first_run_time.is_null()) { first_run_time_ = base::Time::Now(); @@ -49,7 +53,7 @@ GeneralBrowserUsage::~GeneralBrowserUsage() = default; void GeneralBrowserUsage::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterListPref(kMiscMetricsBrowserUsageList); - registry->RegisterBooleanPref(kMiscMetricsDayZeroAtInstall, false); + registry->RegisterStringPref(kMiscMetricsDayZeroVariantAtInstall, {}); } void GeneralBrowserUsage::ReportWeeklyUse() { @@ -64,10 +68,14 @@ void GeneralBrowserUsage::ReportInstallTime() { if (days_since_install < 0 || days_since_install > 30) { return; } - const char* histogram_name = - local_state_->GetBoolean(kMiscMetricsDayZeroAtInstall) - ? kDayZeroOnInstallTime - : kDayZeroOffInstallTime; + std::string day_zero_variant = + local_state_->GetString(kMiscMetricsDayZeroVariantAtInstall); + if (day_zero_variant.empty()) { + return; + } + std::string histogram_name = base::StrCat( + {kDayZeroInstallTimePrefix, base::ToUpperASCII(day_zero_variant), + kDayZeroInstallTimeSuffix}); base::UmaHistogramExactLinear(histogram_name, days_since_install, 31); } #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) diff --git a/components/misc_metrics/general_browser_usage.h b/components/misc_metrics/general_browser_usage.h index 70669d8d8a6..e3be43f910b 100644 --- a/components/misc_metrics/general_browser_usage.h +++ b/components/misc_metrics/general_browser_usage.h @@ -7,6 +7,8 @@ #define BRAVE_COMPONENTS_MISC_METRICS_GENERAL_BROWSER_USAGE_H_ #include +#include +#include #include "base/memory/raw_ptr.h" #include "base/timer/wall_clock_timer.h" @@ -21,15 +23,14 @@ inline constexpr char kWeeklyUseHistogramName[] = "Brave.Core.WeeklyUsage"; inline constexpr char kProfileCountHistogramName[] = "Brave.Core.ProfileCount"; #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) -inline constexpr char kDayZeroOnInstallTime[] = "Brave.DayZero.On.InstallTime"; -inline constexpr char kDayZeroOffInstallTime[] = - "Brave.DayZero.Off.InstallTime"; +inline constexpr char kDayZeroInstallTimePrefix[] = "Brave.DayZero."; +inline constexpr char kDayZeroInstallTimeSuffix[] = ".InstallTime"; #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) class GeneralBrowserUsage { public: GeneralBrowserUsage(PrefService* local_state, - bool day_zero_experiment_enabled, + std::optional day_zero_experiment_variant, bool is_first_run, base::Time first_run_time); ~GeneralBrowserUsage(); diff --git a/components/misc_metrics/general_browser_usage_unittest.cc b/components/misc_metrics/general_browser_usage_unittest.cc index 8a649602e6e..f3382f73374 100644 --- a/components/misc_metrics/general_browser_usage_unittest.cc +++ b/components/misc_metrics/general_browser_usage_unittest.cc @@ -4,6 +4,8 @@ * You can obtain one at https://mozilla.org/MPL/2.0/. */ #include +#include +#include #include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" @@ -14,6 +16,11 @@ namespace misc_metrics { +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) +constexpr char kDayZeroAInstallTime[] = "Brave.DayZero.A.InstallTime"; +constexpr char kDayZeroBInstallTime[] = "Brave.DayZero.B.InstallTime"; +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) + class GeneralBrowserUsageUnitTest : public testing::Test { public: GeneralBrowserUsageUnitTest() @@ -36,12 +43,11 @@ class GeneralBrowserUsageUnitTest : public testing::Test { } protected: - void SetUpUsage(bool day_zero_experiment_enabled, + void SetUpUsage(std::optional day_zero_variant, bool is_first_run, base::Time first_run_time) { general_browser_usage_ = std::make_unique( - &local_state_, day_zero_experiment_enabled, is_first_run, - first_run_time); + &local_state_, day_zero_variant, is_first_run, first_run_time); } content::BrowserTaskEnvironment task_environment_; @@ -51,7 +57,7 @@ class GeneralBrowserUsageUnitTest : public testing::Test { }; TEST_F(GeneralBrowserUsageUnitTest, WeeklyUsage) { - SetUpUsage(false, true, base::Time::Now()); + SetUpUsage({}, true, base::Time::Now()); histogram_tester_.ExpectUniqueSample(kWeeklyUseHistogramName, 0, 1); @@ -68,7 +74,7 @@ TEST_F(GeneralBrowserUsageUnitTest, WeeklyUsage) { #if !BUILDFLAG(IS_ANDROID) TEST_F(GeneralBrowserUsageUnitTest, ProfileCount) { - SetUpUsage(false, true, base::Time::Now()); + SetUpUsage({}, true, base::Time::Now()); histogram_tester_.ExpectTotalCount(kProfileCountHistogramName, 0); @@ -83,48 +89,48 @@ TEST_F(GeneralBrowserUsageUnitTest, ProfileCount) { #endif // !BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) -TEST_F(GeneralBrowserUsageUnitTest, InstallTimeOff) { +TEST_F(GeneralBrowserUsageUnitTest, InstallTimeB) { base::Time install_time = base::Time::Now(); - SetUpUsage(false, true, install_time); + SetUpUsage("B", true, install_time); - histogram_tester_.ExpectUniqueSample(kDayZeroOffInstallTime, 0, 1); + histogram_tester_.ExpectUniqueSample(kDayZeroBInstallTime, 0, 1); task_environment_.FastForwardBy(base::Days(15)); - histogram_tester_.ExpectBucketCount(kDayZeroOffInstallTime, 15, 1); - histogram_tester_.ExpectTotalCount(kDayZeroOnInstallTime, 0); + histogram_tester_.ExpectBucketCount(kDayZeroBInstallTime, 15, 1); + histogram_tester_.ExpectTotalCount(kDayZeroAInstallTime, 0); - SetUpUsage(true, false, install_time); + SetUpUsage("A", false, install_time); // Ensure histogram name does not change if "day zero" is enabled // after install; we only want to report the "day zero on" metric // if it was enabled at install time. - histogram_tester_.ExpectBucketCount(kDayZeroOffInstallTime, 15, 2); - histogram_tester_.ExpectTotalCount(kDayZeroOnInstallTime, 0); + histogram_tester_.ExpectBucketCount(kDayZeroBInstallTime, 15, 2); + histogram_tester_.ExpectTotalCount(kDayZeroAInstallTime, 0); task_environment_.FastForwardBy(base::Days(15)); - histogram_tester_.ExpectBucketCount(kDayZeroOffInstallTime, 30, 1); + histogram_tester_.ExpectBucketCount(kDayZeroBInstallTime, 30, 1); // Ensure there are no more reports past 30 days task_environment_.FastForwardBy(base::Days(5)); - histogram_tester_.ExpectTotalCount(kDayZeroOffInstallTime, 32); - histogram_tester_.ExpectTotalCount(kDayZeroOnInstallTime, 0); + histogram_tester_.ExpectTotalCount(kDayZeroBInstallTime, 32); + histogram_tester_.ExpectTotalCount(kDayZeroAInstallTime, 0); } -TEST_F(GeneralBrowserUsageUnitTest, InstallTimeOn) { +TEST_F(GeneralBrowserUsageUnitTest, InstallTimeA) { base::Time install_time = base::Time::Now(); - SetUpUsage(true, true, install_time); + SetUpUsage("A", true, install_time); - histogram_tester_.ExpectUniqueSample(kDayZeroOnInstallTime, 0, 1); + histogram_tester_.ExpectUniqueSample(kDayZeroAInstallTime, 0, 1); task_environment_.FastForwardBy(base::Days(15)); - histogram_tester_.ExpectBucketCount(kDayZeroOnInstallTime, 15, 1); - histogram_tester_.ExpectTotalCount(kDayZeroOffInstallTime, 0); + histogram_tester_.ExpectBucketCount(kDayZeroAInstallTime, 15, 1); + histogram_tester_.ExpectTotalCount(kDayZeroBInstallTime, 0); - SetUpUsage(false, false, install_time); - histogram_tester_.ExpectBucketCount(kDayZeroOnInstallTime, 15, 2); - histogram_tester_.ExpectTotalCount(kDayZeroOffInstallTime, 0); + SetUpUsage("B", false, install_time); + histogram_tester_.ExpectBucketCount(kDayZeroAInstallTime, 15, 2); + histogram_tester_.ExpectTotalCount(kDayZeroBInstallTime, 0); } #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) diff --git a/components/misc_metrics/pref_names.h b/components/misc_metrics/pref_names.h index 5a2200b1072..6d0f001e43f 100644 --- a/components/misc_metrics/pref_names.h +++ b/components/misc_metrics/pref_names.h @@ -60,8 +60,8 @@ inline constexpr char kMiscMetricsNewTabLocationBarEntriesStorage[] = inline constexpr char kMiscMetricsTotalLocationBarEntriesStorage[] = "brave.misc_metrics.total_location_bar_entries_storage"; -inline constexpr char kMiscMetricsDayZeroAtInstall[] = - "brave.misc_metrics.day_zero_at_install"; +inline constexpr char kMiscMetricsDayZeroVariantAtInstall[] = + "brave.misc_metrics.day_zero_variant_at_install"; } // namespace misc_metrics #endif // BRAVE_COMPONENTS_MISC_METRICS_PREF_NAMES_H_ diff --git a/components/p3a/metric_names.h b/components/p3a/metric_names.h index 7c30006381c..849e1052d3c 100644 --- a/components/p3a/metric_names.h +++ b/components/p3a/metric_names.h @@ -257,8 +257,8 @@ inline constexpr auto kCollectedExpressHistograms = base::MakeFixedFlatSet(base::sorted_unique,{ "Brave.AIChat.UsageDaily.2", "Brave.Core.UsageDaily", - "Brave.DayZero.Off.InstallTime", - "Brave.DayZero.On.InstallTime", + "Brave.DayZero.A.InstallTime", + "Brave.DayZero.B.InstallTime", "Brave.Rewards.EnabledInstallationTime", "Brave.Search.DefaultEngine.4", "Brave.Today.IsEnabled", @@ -329,16 +329,16 @@ inline constexpr auto kEphemeralHistograms = inline constexpr auto kConstellationOnlyHistograms = base::MakeFixedFlatSet(base::sorted_unique,{ "Brave.Core.PrimaryLang", - "Brave.DayZero.Off.InstallTime", - "Brave.DayZero.On.InstallTime", + "Brave.DayZero.A.InstallTime", + "Brave.DayZero.B.InstallTime", }); // List of metrics which will include the stored refcode when transmitted // via the STAR/Constellation protocol. inline constexpr auto kHistogramsWithRefcodeIncluded = base::MakeFixedFlatSet(base::sorted_unique,{ - "Brave.DayZero.Off.InstallTime", - "Brave.DayZero.On.InstallTime", + "Brave.DayZero.A.InstallTime", + "Brave.DayZero.B.InstallTime", }); // clang-format on