From 90adee3719ebff2fd6344c021dfcb6670f1affcd Mon Sep 17 00:00:00 2001 From: Darnell Andries Date: Thu, 2 Nov 2023 20:19:00 -0700 Subject: [PATCH] Add Rewards conversion P3A metrics for Android only --- .../browser/BraveRewardsNativeWorker.java | 9 +++ .../browser/rewards/BraveRewardsPanel.java | 1 + .../android/brave_rewards_native_worker.cc | 8 +++ .../android/brave_rewards_native_worker.h | 2 + .../brave_rewards/browser/rewards_p3a.cc | 66 +++++++++++++++++-- .../brave_rewards/browser/rewards_p3a.h | 19 +++++- .../browser/rewards_service_impl.cc | 3 +- .../browser/test/rewards_p3a_browsertest.cc | 3 +- components/brave_rewards/common/pref_names.cc | 1 + components/brave_rewards/common/pref_names.h | 1 + .../brave_rewards/common/pref_registry.cc | 1 + components/p3a/metric_names.h | 4 ++ 12 files changed, 110 insertions(+), 8 deletions(-) diff --git a/android/java/org/chromium/chrome/browser/BraveRewardsNativeWorker.java b/android/java/org/chromium/chrome/browser/BraveRewardsNativeWorker.java index 4b68b4a9d85..17c265d844a 100644 --- a/android/java/org/chromium/chrome/browser/BraveRewardsNativeWorker.java +++ b/android/java/org/chromium/chrome/browser/BraveRewardsNativeWorker.java @@ -541,6 +541,12 @@ public class BraveRewardsNativeWorker { } } + public void RecordPanelTrigger() { + synchronized (lock) { + BraveRewardsNativeWorkerJni.get().recordPanelTrigger(mNativeBraveRewardsNativeWorker); + } + } + public void SetAutoContributeEnabled(boolean isSetAutoContributeEnabled) { synchronized(lock) { BraveRewardsNativeWorkerJni.get().setAutoContributeEnabled( @@ -839,6 +845,9 @@ public class BraveRewardsNativeWorker { void getAvailableCountries(long nativeBraveRewardsNativeWorker); void disconnectWallet(long nativeBraveRewardsNativeWorker); void refreshPublisher(long nativeBraveRewardsNativeWorker, String publisherKey); + + void recordPanelTrigger(long nativeBraveRewardsNativeWorker); + void createRewardsWallet(long nativeBraveRewardsNativeWorker, String countryCode); void getRewardsParameters(long nativeBraveRewardsNativeWorker); double getVbatDeadline(long nativeBraveRewardsNativeWorker); diff --git a/android/java/org/chromium/chrome/browser/rewards/BraveRewardsPanel.java b/android/java/org/chromium/chrome/browser/rewards/BraveRewardsPanel.java index f31e652e2a2..a1d33aec649 100644 --- a/android/java/org/chromium/chrome/browser/rewards/BraveRewardsPanel.java +++ b/android/java/org/chromium/chrome/browser/rewards/BraveRewardsPanel.java @@ -324,6 +324,7 @@ public class BraveRewardsPanel mPopupWindow.showAsDropDown(mAnchorView, 0, 0); mBraveRewardsNativeWorker.GetExternalWallet(); + mBraveRewardsNativeWorker.RecordPanelTrigger(); } private void setUpViews() { diff --git a/browser/brave_rewards/android/brave_rewards_native_worker.cc b/browser/brave_rewards/android/brave_rewards_native_worker.cc index cb2aed574a4..bbe1893d7e3 100644 --- a/browser/brave_rewards/android/brave_rewards_native_worker.cc +++ b/browser/brave_rewards/android/brave_rewards_native_worker.cc @@ -25,6 +25,7 @@ #include "brave/components/brave_adaptive_captcha/server_util.h" #include "brave/components/brave_ads/browser/ads_service.h" #include "brave/components/brave_ads/core/public/prefs/pref_names.h" +#include "brave/components/brave_rewards/browser/rewards_p3a.h" #include "brave/components/brave_rewards/browser/rewards_service.h" #include "brave/components/brave_rewards/common/pref_names.h" #include "brave/components/brave_rewards/common/rewards_util.h" @@ -1018,6 +1019,13 @@ void BraveRewardsNativeWorker::SetAutoContributeEnabled( } } +void BraveRewardsNativeWorker::RecordPanelTrigger(JNIEnv* env) { + if (brave_rewards_service_) { + brave_rewards_service_->GetP3AConversionMonitor()->RecordPanelTrigger( + brave_rewards::p3a::PanelTrigger::kToolbarButton); + } +} + static void JNI_BraveRewardsNativeWorker_Init( JNIEnv* env, const base::android::JavaParamRef& jcaller) { diff --git a/browser/brave_rewards/android/brave_rewards_native_worker.h b/browser/brave_rewards/android/brave_rewards_native_worker.h index 614c4930115..541f180a3a1 100644 --- a/browser/brave_rewards/android/brave_rewards_native_worker.h +++ b/browser/brave_rewards/android/brave_rewards_native_worker.h @@ -180,6 +180,8 @@ class BraveRewardsNativeWorker JNIEnv* env, const base::android::JavaParamRef& publisher_key); + void RecordPanelTrigger(JNIEnv* env); + void OnCreateRewardsWallet( brave_rewards::mojom::CreateRewardsWalletResult result); diff --git a/components/brave_rewards/browser/rewards_p3a.cc b/components/brave_rewards/browser/rewards_p3a.cc index 7f846307a3c..8a3b62bd488 100644 --- a/components/brave_rewards/browser/rewards_p3a.cc +++ b/components/brave_rewards/browser/rewards_p3a.cc @@ -16,7 +16,6 @@ namespace brave_rewards { namespace p3a { -#if !BUILDFLAG(IS_ANDROID) namespace { // The maximum time difference allowed between the rewards panel opening action @@ -25,8 +24,11 @@ namespace { // enabling. constexpr base::TimeDelta kMaxEnabledCauseTriggerTime = base::Minutes(1); +#if BUILDFLAG(IS_ANDROID) +constexpr base::TimeDelta kReportInterval = base::Days(1); +#endif + } // namespace -#endif // !BUILDFLAG(IS_ANDROID) const char kEnabledSourceHistogramName[] = "Brave.Rewards.EnabledSource"; const char kToolbarButtonTriggerHistogramName[] = @@ -35,8 +37,16 @@ const char kTipsSentHistogramName[] = "Brave.Rewards.TipsSent.2"; const char kAutoContributionsStateHistogramName[] = "Brave.Rewards.AutoContributionsState.3"; const char kAdTypesEnabledHistogramName[] = "Brave.Rewards.AdTypesEnabled"; + +const char kMobileConversionHistogramName[] = "Brave.Rewards.MobileConversion"; +const char kMobilePanelCountHistogramName[] = "Brave.Rewards.MobilePanelCount"; + const int kTipsSentBuckets[] = {0, 1, 3}; +#if BUILDFLAG(IS_ANDROID) +const int kMobilePanelCountBuckets[] = {5, 10, 50}; +#endif + void RecordAutoContributionsState(bool ac_enabled) { UMA_HISTOGRAM_EXACT_LINEAR(kAutoContributionsStateHistogramName, ac_enabled, 2); @@ -76,7 +86,16 @@ void RecordAdTypesEnabled(PrefService* prefs) { UMA_HISTOGRAM_ENUMERATION(kAdTypesEnabledHistogramName, answer); } -ConversionMonitor::ConversionMonitor() = default; +#if BUILDFLAG(IS_ANDROID) +ConversionMonitor::ConversionMonitor(PrefService* prefs) + : prefs_(prefs), + mobile_panel_trigger_count_(prefs, prefs::kP3APanelTriggerCount) { + ReportPeriodicMetrics(); +} +#else +ConversionMonitor::ConversionMonitor(PrefService* prefs) {} +#endif + ConversionMonitor::~ConversionMonitor() = default; void ConversionMonitor::RecordPanelTrigger(PanelTrigger trigger) { @@ -86,7 +105,17 @@ void ConversionMonitor::RecordPanelTrigger(PanelTrigger trigger) { } last_trigger_ = trigger; last_trigger_time_ = base::Time::Now(); -#endif // !BUILDFLAG(IS_ANDROID) +#else + if (prefs_->GetBoolean(prefs::kEnabled)) { + mobile_panel_trigger_count_.AddDelta(1u); + ReportMobilePanelTriggerCount(); + } else { + mobile_trigger_timer_.Start( + FROM_HERE, kMaxEnabledCauseTriggerTime, + base::BindOnce(&ConversionMonitor::OnMobileTriggerTimer, + base::Unretained(this))); + } +#endif } void ConversionMonitor::RecordRewardsEnable() { @@ -105,8 +134,35 @@ void ConversionMonitor::RecordRewardsEnable() { last_trigger_.reset(); last_trigger_time_ = base::Time(); -#endif // !BUILDFLAG(IS_ANDROID) +#else + mobile_trigger_timer_.Stop(); + OnMobileTriggerTimer(); +#endif } +#if BUILDFLAG(IS_ANDROID) + +void ConversionMonitor::ReportPeriodicMetrics() { + ReportMobilePanelTriggerCount(); + daily_timer_.Start(FROM_HERE, base::Time::Now() + kReportInterval, + base::BindOnce(&ConversionMonitor::ReportPeriodicMetrics, + base::Unretained(this))); +} + +void ConversionMonitor::OnMobileTriggerTimer() { + UMA_HISTOGRAM_BOOLEAN(kMobileConversionHistogramName, + prefs_->GetBoolean(prefs::kEnabled)); +} + +void ConversionMonitor::ReportMobilePanelTriggerCount() { + uint64_t total = mobile_panel_trigger_count_.GetWeeklySum(); + if (total == 0) { + return; + } + p3a_utils::RecordToHistogramBucket(kMobilePanelCountHistogramName, + kMobilePanelCountBuckets, total); +} +#endif + } // namespace p3a } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_p3a.h b/components/brave_rewards/browser/rewards_p3a.h index dfe59d8adc9..706049e2048 100644 --- a/components/brave_rewards/browser/rewards_p3a.h +++ b/components/brave_rewards/browser/rewards_p3a.h @@ -6,7 +6,11 @@ #ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_BROWSER_REWARDS_P3A_H_ #define BRAVE_COMPONENTS_BRAVE_REWARDS_BROWSER_REWARDS_P3A_H_ +#include "base/memory/raw_ptr.h" #include "base/time/time.h" +#include "base/timer/timer.h" +#include "base/timer/wall_clock_timer.h" +#include "brave/components/time_period_storage/weekly_storage.h" #include "third_party/abseil-cpp/absl/types/optional.h" class PrefService; @@ -19,6 +23,8 @@ extern const char kToolbarButtonTriggerHistogramName[]; extern const char kTipsSentHistogramName[]; extern const char kAutoContributionsStateHistogramName[]; extern const char kAdTypesEnabledHistogramName[]; +extern const char kMobileConversionHistogramName[]; +extern const char kMobilePanelCountHistogramName[]; enum class AutoContributionsState { kNoWallet, @@ -52,7 +58,7 @@ void RecordAdTypesEnabled(PrefService* prefs); class ConversionMonitor { public: - ConversionMonitor(); + explicit ConversionMonitor(PrefService* prefs); ~ConversionMonitor(); ConversionMonitor(const ConversionMonitor&) = delete; @@ -67,8 +73,19 @@ class ConversionMonitor { void RecordRewardsEnable(); private: +#if BUILDFLAG(IS_ANDROID) + void ReportPeriodicMetrics(); + void OnMobileTriggerTimer(); + void ReportMobilePanelTriggerCount(); + + raw_ptr prefs_; + WeeklyStorage mobile_panel_trigger_count_; + base::OneShotTimer mobile_trigger_timer_; + base::WallClockTimer daily_timer_; +#else absl::optional last_trigger_; base::Time last_trigger_time_; +#endif }; } // namespace p3a diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 7f0872fee68..249067a7262 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -292,7 +292,8 @@ RewardsServiceImpl::RewardsServiceImpl(Profile* profile) new DiagnosticLog(profile_->GetPath().Append(kDiagnosticLogPath), kDiagnosticLogMaxFileSize, kDiagnosticLogKeepNumLines)), - notification_service_(new RewardsNotificationServiceImpl(profile)) { + notification_service_(new RewardsNotificationServiceImpl(profile)), + conversion_monitor_(profile->GetPrefs()) { // Set up the rewards data source content::URLDataSource::Add(profile_, std::make_unique(profile_)); diff --git a/components/brave_rewards/browser/test/rewards_p3a_browsertest.cc b/components/brave_rewards/browser/test/rewards_p3a_browsertest.cc index 4a6b7208feb..4d9da5c2549 100644 --- a/components/brave_rewards/browser/test/rewards_p3a_browsertest.cc +++ b/components/brave_rewards/browser/test/rewards_p3a_browsertest.cc @@ -24,6 +24,7 @@ #include "brave/components/brave_rewards/common/pref_names.h" #include "brave/components/constants/brave_paths.h" #include "brave/components/ntp_background_images/common/pref_names.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/network_session_configurator/common/network_switches.h" @@ -185,7 +186,7 @@ IN_PROC_BROWSER_TEST_F(RewardsP3ABrowserTest, ToggleAdTypes) { #if !BUILDFLAG(IS_ANDROID) IN_PROC_BROWSER_TEST_F(RewardsP3ABrowserTest, Conversion) { - p3a::ConversionMonitor conversion_monitor; + p3a::ConversionMonitor conversion_monitor(g_browser_process->local_state()); histogram_tester_->ExpectTotalCount(p3a::kEnabledSourceHistogramName, 0); diff --git a/components/brave_rewards/common/pref_names.cc b/components/brave_rewards/common/pref_names.cc index e0f4a41e0ea..427ccefbbf0 100644 --- a/components/brave_rewards/common/pref_names.cc +++ b/components/brave_rewards/common/pref_names.cc @@ -38,6 +38,7 @@ const char kUpholdAnonAddress[] = const char kBadgeText[] = "brave.rewards.badge_text"; const char kUseRewardsStagingServer[] = "brave.rewards.use_staging_server"; const char kExternalWalletType[] = "brave.rewards.external_wallet_type"; +const char kP3APanelTriggerCount[] = "brave.rewards.p3a_panel_trigger_count"; const char kPromotionLastFetchStamp[] = "brave.rewards.promotion_last_fetch_stamp"; const char kPromotionCorruptedMigrated[] = diff --git a/components/brave_rewards/common/pref_names.h b/components/brave_rewards/common/pref_names.h index 6b09f1f5222..bd3a110a49c 100644 --- a/components/brave_rewards/common/pref_names.h +++ b/components/brave_rewards/common/pref_names.h @@ -35,6 +35,7 @@ extern const char kExternalWallets[]; // DEPRECATED extern const char kBadgeText[]; extern const char kUseRewardsStagingServer[]; extern const char kExternalWalletType[]; +extern const char kP3APanelTriggerCount[]; // Defined in core extern const char kServerPublisherListStamp[]; diff --git a/components/brave_rewards/common/pref_registry.cc b/components/brave_rewards/common/pref_registry.cc index 75b61a6ed8e..707150ef47b 100644 --- a/components/brave_rewards/common/pref_registry.cc +++ b/components/brave_rewards/common/pref_registry.cc @@ -26,6 +26,7 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterStringPref(prefs::kDeclaredGeo, ""); registry->RegisterStringPref(prefs::kUserVersion, ""); registry->RegisterDictionaryPref(prefs::kExternalWallets); + registry->RegisterListPref(prefs::kP3APanelTriggerCount); registry->RegisterUint64Pref(prefs::kServerPublisherListStamp, 0ull); registry->RegisterStringPref(prefs::kUpholdAnonAddress, ""); registry->RegisterStringPref(prefs::kBadgeText, "1"); diff --git a/components/p3a/metric_names.h b/components/p3a/metric_names.h index de2e2f1dd3b..d39eaaa0b10 100644 --- a/components/p3a/metric_names.h +++ b/components/p3a/metric_names.h @@ -58,6 +58,8 @@ constexpr inline auto kCollectedTypicalHistograms = "Brave.Rewards.AdTypesEnabled", "Brave.Rewards.AutoContributionsState.3", "Brave.Rewards.EnabledSource", + "Brave.Rewards.MobileConversion", + "Brave.Rewards.MobilePanelCount", "Brave.Rewards.TipsState.2", "Brave.Rewards.ToolbarButtonTrigger", "Brave.Rewards.WalletBalance.3", @@ -245,6 +247,8 @@ constexpr inline auto kEphemeralHistograms = "Brave.PrivacyHub.Views", "Brave.Rewards.EnabledInstallationTime", "Brave.Rewards.EnabledSource", + "Brave.Rewards.MobileConversion", + "Brave.Rewards.MobilePanelCount", "Brave.Rewards.TipsSent", "Brave.Rewards.ToolbarButtonTrigger", "Brave.Search.QueriesBeforeChurn",