diff --git a/components/brave_ads/browser/ads_service_impl.cc b/components/brave_ads/browser/ads_service_impl.cc index 84853aaeeef6..f564d532faf9 100644 --- a/components/brave_ads/browser/ads_service_impl.cc +++ b/components/brave_ads/browser/ads_service_impl.cc @@ -1708,7 +1708,8 @@ void AdsServiceImpl::OnPrefsChanged(const std::string& pref) { } // Record P3A. - brave_rewards::UpdateAdsP3AOnPreferenceChange(profile_->GetPrefs(), pref); + brave_rewards::p3a::UpdateAdsStateOnPreferenceChange(profile_->GetPrefs(), + pref); } else if (pref == ads::prefs::kIdleTimeThreshold) { StartCheckIdleStateTimer(); } else if (pref == brave_rewards::prefs::kWalletBrave) { diff --git a/components/brave_rewards/browser/rewards_p3a.cc b/components/brave_rewards/browser/rewards_p3a.cc index 4ce706c730c6..80b20bef02d0 100644 --- a/components/brave_rewards/browser/rewards_p3a.cc +++ b/components/brave_rewards/browser/rewards_p3a.cc @@ -14,10 +14,41 @@ #include "brave/components/brave_rewards/common/pref_names.h" #include "components/prefs/pref_service.h" +namespace { + +uint64_t RoundProbiToUint64(base::StringPiece probi) { + if (probi.size() < 18) + return 0; + uint64_t grant = 0; + base::StringToUint64(probi.substr(0, probi.size() - 18), &grant); + return grant; +} + +} // namespace + namespace brave_rewards { +namespace p3a { -void RecordWalletBalanceP3A(bool wallet_created, bool rewards_enabled, - size_t b) { +void RecordWalletState(const WalletState& state) { + int answer = 0; + if (state.wallet_created && !state.rewards_enabled) { + answer = 5; + } else if (state.rewards_enabled) { + DCHECK(state.wallet_created); + if (state.grants_claimed && state.funds_added) { + answer = 4; + } else if (state.funds_added) { + answer = 3; + } else if (state.grants_claimed) { + answer = 2; + } else { + answer = 1; + } + } + UMA_HISTOGRAM_EXACT_LINEAR("Brave.Rewards.WalletState", answer, 5); +} + +void RecordWalletBalance(bool wallet_created, bool rewards_enabled, size_t b) { int answer = 0; if (wallet_created && !rewards_enabled) { answer = 1; @@ -34,19 +65,19 @@ void RecordWalletBalanceP3A(bool wallet_created, bool rewards_enabled, UMA_HISTOGRAM_EXACT_LINEAR("Brave.Rewards.WalletBalance.2", answer, 4); } -void RecordAutoContributionsState(AutoContributionsP3AState state, int count) { +void RecordAutoContributionsState(AutoContributionsState state, int count) { DCHECK_GE(count, 0); int answer = 0; switch (state) { - case AutoContributionsP3AState::kNoWallet: + case AutoContributionsState::kNoWallet: break; - case AutoContributionsP3AState::kRewardsDisabled: + case AutoContributionsState::kRewardsDisabled: answer = 1; break; - case AutoContributionsP3AState::kWalletCreatedAutoContributeOff: + case AutoContributionsState::kWalletCreatedAutoContributeOff: answer = 2; break; - case AutoContributionsP3AState::kAutoContributeOn: + case AutoContributionsState::kAutoContributeOn: switch (count) { case 0: answer = 3; @@ -90,75 +121,66 @@ void RecordTipsState(bool wallet_created, UMA_HISTOGRAM_EXACT_LINEAR("Brave.Rewards.TipsState.2", answer, 5); } -void RecordAdsState(AdsP3AState state) { +void RecordAdsState(AdsState state) { UMA_HISTOGRAM_ENUMERATION("Brave.Rewards.AdsState.2", state); } -void UpdateAdsP3AOnPreferenceChange(PrefService *prefs, - const std::string& pref) { +void UpdateAdsStateOnPreferenceChange(PrefService* prefs, + const std::string& pref) { const bool ads_enabled = prefs->GetBoolean(ads::prefs::kEnabled); if (pref == ads::prefs::kEnabled) { if (ads_enabled) { - brave_rewards::RecordAdsState(AdsP3AState::kAdsEnabled); + RecordAdsState(AdsState::kAdsEnabled); prefs->SetBoolean(brave_ads::prefs::kAdsWereDisabled, false); } else { // Apparently, the pref was disabled. - brave_rewards::RecordAdsState( - AdsP3AState::kAdsEnabledThenDisabledRewardsOn); + RecordAdsState(AdsState::kAdsEnabledThenDisabledRewardsOn); prefs->SetBoolean(brave_ads::prefs::kAdsWereDisabled, true); } } } -void MaybeRecordInitialAdsP3AState(PrefService* prefs) { +void MaybeRecordInitialAdsState(PrefService* prefs) { if (!prefs->GetBoolean(brave_ads::prefs::kHasAdsP3AState)) { const bool ads_state = prefs->GetBoolean(ads::prefs::kEnabled); - RecordAdsState(ads_state ? AdsP3AState::kAdsEnabled - : AdsP3AState::kAdsDisabled); + RecordAdsState(ads_state ? AdsState::kAdsEnabled : AdsState::kAdsDisabled); prefs->SetBoolean(brave_ads::prefs::kHasAdsP3AState, true); } } void RecordNoWalletCreatedForAllMetrics() { - RecordWalletBalanceP3A(false, false, 0); - RecordAutoContributionsState(AutoContributionsP3AState::kNoWallet, 0); + RecordWalletState({}); + RecordWalletBalance(false, false, 0); + RecordAutoContributionsState(AutoContributionsState::kNoWallet, 0); RecordTipsState(false, false, 0, 0); - RecordAdsState(AdsP3AState::kNoWallet); + RecordAdsState(AdsState::kNoWallet); } void RecordRewardsDisabledForSomeMetrics() { - RecordWalletBalanceP3A(true, false, 1); - RecordAutoContributionsState(AutoContributionsP3AState::kRewardsDisabled, 0); + RecordWalletBalance(true, false, 1); + RecordAutoContributionsState(AutoContributionsState::kRewardsDisabled, 0); RecordTipsState(true, false, 0, 0); // Ads state is handled separately. } - -double CalcWalletBalanceForP3A(base::flat_map wallets, - double user_funds) { +double CalcWalletBalance(base::flat_map wallets, + double user_funds) { double balance_minus_grant = 0.0; for (const auto& wallet : wallets) { - // Skip anonymous wallet, since it can contain grants. - if (wallet.first == "anonymous") { + // Skip anonymous and unblinded wallets, since they can contain grants. + if (wallet.first == "anonymous" || wallet.first == "blinded") { continue; } balance_minus_grant += static_cast(wallet.second); } - // `user_funds` is the amount of user-funded BAT - // in the anonymous wallet (ex: not grants). + // |user_funds| is the amount of user-funded BAT in the anonymous + // wallet (ex: not grants). balance_minus_grant += user_funds; return balance_minus_grant; } -uint64_t RoundProbiToUint64(base::StringPiece probi) { - if (probi.size() < 18) return 0; - uint64_t grant = 0; - base::StringToUint64(probi.substr(0, probi.size() - 18), &grant); - return grant; -} - -void ExtractAndLogP3AStats(const base::DictionaryValue& dict) { +void ExtractAndLogStats(const base::DictionaryValue& dict) { const base::Value* probi_value = dict.FindPath({"walletProperties", "probi_"}); if (!probi_value || !probi_value->is_string()) { @@ -195,7 +217,8 @@ void ExtractAndLogP3AStats(const base::DictionaryValue& dict) { } const uint64_t total = RoundProbiToUint64(probi_value->GetString()) - total_grants; - RecordWalletBalanceP3A(true, true, total); + RecordWalletBalance(true, true, total); } +} // namespace p3a } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_p3a.h b/components/brave_rewards/browser/rewards_p3a.h index f726404addf9..ee1ed36b769f 100644 --- a/components/brave_rewards/browser/rewards_p3a.h +++ b/components/brave_rewards/browser/rewards_p3a.h @@ -21,25 +21,36 @@ class DictionaryValue; } namespace brave_rewards { +namespace p3a { -void RecordWalletBalanceP3A(bool wallet_created, bool rewards_enabled, - size_t balance); +struct WalletState { + bool wallet_created = false; + bool rewards_enabled = false; + bool grants_claimed = false; + bool funds_added = false; +}; + +void RecordWalletState(const WalletState& state); -enum class AutoContributionsP3AState { +void RecordWalletBalance(bool wallet_created, + bool rewards_enabled, + size_t balance); + +enum class AutoContributionsState { kNoWallet, kRewardsDisabled, kWalletCreatedAutoContributeOff, kAutoContributeOn, }; -void RecordAutoContributionsState(AutoContributionsP3AState state, int count); +void RecordAutoContributionsState(AutoContributionsState state, int count); void RecordTipsState(bool wallet_created, bool rewards_enabled, int one_time_count, int recurring_count); -enum class AdsP3AState { +enum class AdsState { kNoWallet, kRewardsDisabled, kAdsDisabled, @@ -49,26 +60,25 @@ enum class AdsP3AState { kMaxValue = kAdsEnabledThenDisabledRewardsOff, }; -void RecordAdsState(AdsP3AState state); +void RecordAdsState(AdsState state); -void UpdateAdsP3AOnPreferenceChange(PrefService* prefs, - const std::string& pref); +void UpdateAdsStateOnPreferenceChange(PrefService* prefs, + const std::string& pref); // Records an initial metric state ("disabled" or "enabled") if it was not done // before. Intended to be called if the user has already created a wallet. -void MaybeRecordInitialAdsP3AState(PrefService* local_state); +void MaybeRecordInitialAdsState(PrefService* local_state); void RecordNoWalletCreatedForAllMetrics(); void RecordRewardsDisabledForSomeMetrics(); -double CalcWalletBalanceForP3A(base::flat_map wallets, - double user_funds); - -uint64_t RoundProbiToUint64(base::StringPiece probi); +double CalcWalletBalance(base::flat_map wallets, + double user_funds); -void ExtractAndLogP3AStats(const base::DictionaryValue& dict); +void ExtractAndLogStats(const base::DictionaryValue& dict); +} // namespace p3a } // namespace brave_rewards #endif // BRAVE_COMPONENTS_BRAVE_REWARDS_BROWSER_REWARDS_P3A_H_ diff --git a/components/brave_rewards/browser/rewards_service.cc b/components/brave_rewards/browser/rewards_service.cc index fca3766f96ec..4ec3c33ee5f5 100644 --- a/components/brave_rewards/browser/rewards_service.cc +++ b/components/brave_rewards/browser/rewards_service.cc @@ -52,6 +52,7 @@ void RewardsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { base::TimeDelta::FromSeconds(30)); registry->RegisterBooleanPref(prefs::kBackupSucceeded, false); registry->RegisterBooleanPref(prefs::kUserHasFunded, false); + registry->RegisterBooleanPref(prefs::kUserHasClaimedGrant, false); registry->RegisterTimePref(prefs::kAddFundsNotification, base::Time()); registry->RegisterBooleanPref(prefs::kEnabled, false); registry->RegisterDictionaryPref(prefs::kExternalWallets); diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 71e4efa45151..8c036b9c26ae 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -91,8 +91,6 @@ #include "brave/components/ipfs/ipfs_utils.h" #endif using net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES; -using std::placeholders::_1; -using std::placeholders::_2; namespace brave_rewards { @@ -166,7 +164,7 @@ std::pair LoadStateOnFileTaskRunner( return result; } - ExtractAndLogP3AStats(*dict); + p3a::ExtractAndLogStats(*dict); result.second = std::move(*dict); return result; @@ -418,8 +416,8 @@ void RewardsServiceImpl::OnPreferenceChanged(const std::string& key) { StartLedgerProcessIfNecessary(); } else { // Just record the disabled state. - RecordAutoContributionsState( - AutoContributionsP3AState::kWalletCreatedAutoContributeOff, 0); + p3a::RecordAutoContributionsState( + p3a::AutoContributionsState::kWalletCreatedAutoContributeOff, 0); } } @@ -427,7 +425,8 @@ void RewardsServiceImpl::OnPreferenceChanged(const std::string& key) { if (IsRewardsEnabled()) { RecordBackendP3AStats(); } else { - RecordRewardsDisabledForSomeMetrics(); + p3a::RecordRewardsDisabledForSomeMetrics(); + p3a::RecordWalletState({.wallet_created = true}); } } } @@ -842,14 +841,24 @@ void RewardsServiceImpl::OnLedgerInitialized(ledger::type::Result result) { if (IsRewardsEnabled()) { RecordBackendP3AStats(); } else { - RecordRewardsDisabledForSomeMetrics(); + p3a::RecordRewardsDisabledForSomeMetrics(); } + GetBraveWallet( + base::BindOnce(&RewardsServiceImpl::OnGetBraveWalletForP3A, AsWeakPtr())); + for (auto& observer : observers_) { observer.OnRewardsInitialized(this); } } +void RewardsServiceImpl::OnGetBraveWalletForP3A( + ledger::type::BraveWalletPtr wallet) { + if (!wallet) { + p3a::RecordNoWalletCreatedForAllMetrics(); + } +} + void RewardsServiceImpl::OnGetAutoContributeProperties( const GetAutoContributePropertiesCallback& callback, ledger::type::AutoContributePropertiesPtr properties) { @@ -921,10 +930,10 @@ void RewardsServiceImpl::OnLedgerStateLoaded( if (state.second.is_dict()) { // Record stats. RecordBackendP3AStats(); - MaybeRecordInitialAdsP3AState(profile_->GetPrefs()); + p3a::MaybeRecordInitialAdsState(profile_->GetPrefs()); } if (state.first.empty()) { - RecordNoWalletCreatedForAllMetrics(); + p3a::RecordNoWalletCreatedForAllMetrics(); } // Run callbacks. @@ -1312,6 +1321,9 @@ void RewardsServiceImpl::OnAttestPromotion( return; } + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kUserHasClaimedGrant, true); + for (auto& observer : observers_) { observer.OnPromotionFinished(this, result, promotion->Clone()); } @@ -2767,19 +2779,29 @@ void RewardsServiceImpl::OnFetchBalance( FetchBalanceCallback callback, const ledger::type::Result result, ledger::type::BalancePtr balance) { + PrefService* pref_service = profile_->GetPrefs(); + + // Record wallet state stats + if (IsRewardsEnabled()) { + const bool grants_claimed = + pref_service->GetBoolean(prefs::kUserHasClaimedGrant); + p3a::RecordWalletState( + {.wallet_created = true, + .rewards_enabled = true, + .grants_claimed = grants_claimed, + .funds_added = balance && balance->user_funds > 0}); + } + if (balance) { if (balance->total > 0) { - profile_->GetPrefs()->SetBoolean(prefs::kUserHasFunded, true); + pref_service->SetBoolean(prefs::kUserHasFunded, true); } - // Record stats. - double balance_minus_grant = CalcWalletBalanceForP3A( - balance->wallets, - balance->user_funds); - RecordWalletBalanceP3A( - true, - true, - static_cast(balance_minus_grant)); + // Record wallet balance stats + double balance_minus_grant = + p3a::CalcWalletBalance(balance->wallets, balance->user_funds); + p3a::RecordWalletBalance(true, true, + static_cast(balance_minus_grant)); } std::move(callback).Run(result, std::move(balance)); @@ -3012,7 +3034,7 @@ void RewardsServiceImpl::OnRecordBackendP3AStatsContributions( queued_recurring = recurring_donation_size; } - RecordTipsState(true, true, tips, queued_recurring); + p3a::RecordTipsState(true, true, tips, queued_recurring); GetAutoContributeEnabled(base::BindOnce( &RewardsServiceImpl::OnRecordBackendP3AStatsAC, @@ -3023,10 +3045,11 @@ void RewardsServiceImpl::OnRecordBackendP3AStatsContributions( void RewardsServiceImpl::OnRecordBackendP3AStatsAC( const int auto_contributions, bool ac_enabled) { - const auto auto_contributions_state = ac_enabled ? - AutoContributionsP3AState::kAutoContributeOn : - AutoContributionsP3AState::kWalletCreatedAutoContributeOff; - RecordAutoContributionsState(auto_contributions_state, auto_contributions); + const auto auto_contributions_state = + ac_enabled ? p3a::AutoContributionsState::kAutoContributeOn + : p3a::AutoContributionsState::kWalletCreatedAutoContributeOff; + p3a::RecordAutoContributionsState(auto_contributions_state, + auto_contributions); } #if defined(OS_ANDROID) diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 871d6823c3d6..67351041c388 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -688,6 +688,8 @@ class RewardsServiceImpl : public RewardsService, const std::string& publisher_key, const std::string& publisher_name) override; + void OnGetBraveWalletForP3A(ledger::type::BraveWalletPtr wallet); + bool Connected() const; void ConnectionClosed(); void AddPrivateObserver(RewardsServicePrivateObserver* observer) override; diff --git a/components/brave_rewards/common/pref_names.cc b/components/brave_rewards/common/pref_names.cc index 42e0efc3fa98..da6c30300f9c 100644 --- a/components/brave_rewards/common/pref_names.cc +++ b/components/brave_rewards/common/pref_names.cc @@ -17,6 +17,7 @@ const char kBackupNotificationInterval[] = "brave.rewards.backup_notification_interval"; const char kBackupSucceeded[] = "brave.rewards.backup_succeeded"; const char kUserHasFunded[] = "brave.rewards.user_has_funded"; +const char kUserHasClaimedGrant[] = "brave.rewards.user_has_claimed_grant"; const char kAddFundsNotification[] = "brave.rewards.add_funds_notification"; const char kNotificationStartupDelay[] = diff --git a/components/brave_rewards/common/pref_names.h b/components/brave_rewards/common/pref_names.h index cbc10fb755a3..30e1511ac891 100644 --- a/components/brave_rewards/common/pref_names.h +++ b/components/brave_rewards/common/pref_names.h @@ -16,6 +16,7 @@ extern const char kNotificationTimerInterval[]; extern const char kBackupNotificationInterval[]; extern const char kBackupSucceeded[]; extern const char kUserHasFunded[]; +extern const char kUserHasClaimedGrant[]; extern const char kAddFundsNotification[]; extern const char kNotificationStartupDelay[]; extern const char kExternalWallets[]; // DEPRECATED diff --git a/components/p3a/brave_p3a_service.cc b/components/p3a/brave_p3a_service.cc index a84b6498494c..9e7444a777e6 100644 --- a/components/p3a/brave_p3a_service.cc +++ b/components/p3a/brave_p3a_service.cc @@ -20,12 +20,12 @@ #include "base/strings/string_number_conversions.h" #include "base/task/post_task.h" #include "base/trace_event/trace_event.h" -#include "brave/components/brave_stats/browser/brave_stats_updater_util.h" #include "brave/browser/version_info.h" #include "brave/common/brave_channel_info.h" #include "brave/common/pref_names.h" #include "brave/components/brave_prochlo/prochlo_message.pb.h" #include "brave/components/brave_referrals/common/pref_names.h" +#include "brave/components/brave_stats/browser/brave_stats_updater_util.h" #include "brave/components/p3a/brave_p2a_protocols.h" #include "brave/components/p3a/brave_p3a_log_store.h" #include "brave/components/p3a/brave_p3a_scheduler.h" @@ -80,6 +80,7 @@ constexpr const char* kCollectedHistograms[] = { "Brave.Rewards.AutoContributionsState.2", "Brave.Rewards.TipsState.2", "Brave.Rewards.WalletBalance.2", + "Brave.Rewards.WalletState", "Brave.Savings.BandwidthSavingsMB", "Brave.Search.DefaultEngine.4", "Brave.Shields.UsageStatus",