diff --git a/components/brave_ads/browser/ads_service_factory.cc b/components/brave_ads/browser/ads_service_factory.cc index f68e30b47906..22e90f7fe5db 100644 --- a/components/brave_ads/browser/ads_service_factory.cc +++ b/components/brave_ads/browser/ads_service_factory.cc @@ -1,4 +1,5 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -11,6 +12,7 @@ #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_store.h" #if BUILDFLAG(BRAVE_ADS_ENABLED) #include "brave/components/brave_ads/browser/ads_service_impl.h" @@ -19,6 +21,8 @@ #include "brave/components/brave_rewards/browser/rewards_service_factory.h" #endif +class PrefStore; + namespace brave_ads { // static @@ -76,10 +80,41 @@ bool AdsServiceFactory::ServiceIsNULLWhileTesting() const { void AdsServiceFactory::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { + if (ShouldMigratePrefs(registry)) { + // prefs::kBraveAdsPrefsVersion should default to 1 for legacy installations + // so that preferences are migrated from version 1 to the current version + registry->RegisterIntegerPref(prefs::kBraveAdsPrefsVersion, + prefs::kBraveAdsPrefsDefaultVersion); + } else { + registry->RegisterIntegerPref(prefs::kBraveAdsPrefsVersion, + prefs::kBraveAdsPrefsCurrentVersion); + } + registry->RegisterBooleanPref(prefs::kBraveAdsEnabled, false); + registry->RegisterUint64Pref(prefs::kBraveAdsPerHour, 2); - registry->RegisterUint64Pref(prefs::kBraveAdsPerDay, 6); + + #if defined(OS_ANDROID) + registry->RegisterUint64Pref(prefs::kBraveAdsPerDay, 12); + #else + registry->RegisterUint64Pref(prefs::kBraveAdsPerDay, 20); + #endif + registry->RegisterIntegerPref(prefs::kBraveAdsIdleThreshold, 15); } +bool AdsServiceFactory::ShouldMigratePrefs( + user_prefs::PrefRegistrySyncable* registry) const { + // If prefs::kBraveAdsEnabled does not exist then this must be a fresh + // installion so we do not need to migrate + auto pref_store = registry->defaults(); + + const base::Value* value = nullptr; + if (!pref_store->GetValue(prefs::kBraveAdsEnabled, &value)) { + return false; + } + + return true; +} + } // namespace brave_ads diff --git a/components/brave_ads/browser/ads_service_factory.h b/components/brave_ads/browser/ads_service_factory.h index 782a6e81bc8e..e99a26b0b84b 100644 --- a/components/brave_ads/browser/ads_service_factory.h +++ b/components/brave_ads/browser/ads_service_factory.h @@ -1,4 +1,5 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -13,8 +14,7 @@ class Profile; namespace brave_ads { class AdsService; -// Singleton that owns all AdsService and associates them with -// Profiles. +// Singleton that owns all AdsService and associates them with Profiles. class AdsServiceFactory : public BrowserContextKeyedServiceFactory { public: static brave_ads::AdsService* GetForProfile(Profile* profile); @@ -35,10 +35,11 @@ class AdsServiceFactory : public BrowserContextKeyedServiceFactory { bool ServiceIsNULLWhileTesting() const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override; + bool ShouldMigratePrefs(user_prefs::PrefRegistrySyncable* registry) const; DISALLOW_COPY_AND_ASSIGN(AdsServiceFactory); }; -} // namepsace brave_ads +} // namespace brave_ads #endif // BRAVE_COMPONENTS_BRAVE_ADS_ADS_SERVICE_FACTORY_H_ diff --git a/components/brave_ads/browser/ads_service_impl.cc b/components/brave_ads/browser/ads_service_impl.cc index 1db364a725d0..5553475550d5 100644 --- a/components/brave_ads/browser/ads_service_impl.cc +++ b/components/brave_ads/browser/ads_service_impl.cc @@ -286,6 +286,8 @@ AdsServiceImpl::AdsServiceImpl(Profile* profile) base::Bind(&AdsServiceImpl::OnPrefsChanged, base::Unretained(this))); + MigratePrefs(); + auto* display_service_impl = static_cast(display_service_); @@ -441,6 +443,102 @@ void AdsServiceImpl::Shutdown() { notification_ids_.clear(); } +void AdsServiceImpl::MigratePrefs() const { + auto source_version = GetPrefsVersion(); + auto dest_version = prefs::kBraveAdsPrefsCurrentVersion; + + if (!MigratePrefs(source_version, dest_version, true)) { + // Migration dry-run failed, so do not migrate preferences + LOG(ERROR) << "Failed to migrate Ads preferences from version " + << source_version << " to " << dest_version; + + return; + } + + MigratePrefs(source_version, dest_version); +} + +bool AdsServiceImpl::MigratePrefs( + const int source_version, + const int dest_version, + const bool is_dry_run) const { + DCHECK(source_version <= dest_version) << "Invalid migration path"; + + if (source_version == dest_version) { + if (!is_dry_run) { + LOG(INFO) << "Ads preferences are up to date on version " << dest_version; + } + + return true; + } + + // Migration paths should be added to the below map, i.e. + // + // {{1, 2}, &AdsServiceImpl::MigratePrefsVersion1To2}, + // {{2, 3}, &AdsServiceImpl::MigratePrefsVersion2To3}, + // {{3, 4}, &AdsServiceImpl::MigratePrefsVersion3To4} + + static std::map, void (AdsServiceImpl::*)() const> + mappings { + // {{from version, to version}, function} + {{1, 2}, &AdsServiceImpl::MigratePrefsVersion1To2} + }; + + // Cycle through migration paths, i.e. if upgrading from version 2 to 5 we + // should migrate version 2 to 3, then 3 to 4 and finally version 4 to 5 + + int from_version = source_version; + int to_version = from_version + 1; + + do { + auto mapping = mappings.find({from_version, to_version}); + if (mapping == mappings.end()) { + // Migration path does not exist. It is highly recommended to perform a + // dry-run before migrating preferences + return false; + } + + if (!is_dry_run) { + LOG(INFO) << "Migrating Ads preferences from mapping version " + << from_version << " to " << to_version; + + (this->*(mapping->second))(); + + profile_->GetPrefs()->SetInteger(prefs::kBraveAdsPrefsVersion, + to_version); + } + + from_version++; + if (to_version < dest_version) { + to_version++; + } + } while (from_version != to_version); + + if (!is_dry_run) { + LOG(INFO) << "Successfully migrated Ads preferences from version " + << source_version << " to " << dest_version; + } + + return true; +} + +void AdsServiceImpl::MigratePrefsVersion1To2() const { + DCHECK_EQ(1, GetPrefsVersion()) << "Invalid migration path"; + + // Unlike Muon, Ads per day are not configurable in the UI so we can safely + // migrate to the new value + + #if defined(OS_ANDROID) + profile_->GetPrefs()->SetUint64(prefs::kBraveAdsPerDay, 12); + #else + profile_->GetPrefs()->SetUint64(prefs::kBraveAdsPerDay, 20); + #endif +} + +int AdsServiceImpl::GetPrefsVersion() const { + return profile_->GetPrefs()->GetInteger(prefs::kBraveAdsPrefsVersion); +} + void AdsServiceImpl::OnPrefsChanged(const std::string& pref) { if (pref == prefs::kBraveAdsEnabled || pref == brave_rewards::prefs::kBraveRewardsEnabled) { diff --git a/components/brave_ads/browser/ads_service_impl.h b/components/brave_ads/browser/ads_service_impl.h index 342d90cfb905..5cc58f302387 100644 --- a/components/brave_ads/browser/ads_service_impl.h +++ b/components/brave_ads/browser/ads_service_impl.h @@ -168,6 +168,13 @@ class AdsServiceImpl : public AdsService, void OnSaved(const ads::OnSaveCallback& callback, bool success); void OnReset(const ads::OnResetCallback& callback, bool success); void OnTimer(uint32_t timer_id); + void MigratePrefs() const; + bool MigratePrefs( + const int source_version, + const int dest_version, + const bool is_dry_run = false) const; + void MigratePrefsVersion1To2() const; + int GetPrefsVersion() const; void OnPrefsChanged(const std::string& pref); void OnCreate(); void OnInitialize(); diff --git a/components/brave_ads/common/pref_names.cc b/components/brave_ads/common/pref_names.cc index 4cefaca44151..b0c292d30316 100644 --- a/components/brave_ads/common/pref_names.cc +++ b/components/brave_ads/common/pref_names.cc @@ -1,15 +1,22 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "brave/components/brave_ads/common/pref_names.h" namespace brave_ads { + namespace prefs { const char kBraveAdsEnabled[] = "brave.brave_ads.enabled"; const char kBraveAdsPerHour[] = "brave.brave_ads.ads_per_hour"; const char kBraveAdsPerDay[] = "brave.brave_ads.ads_per_day"; const char kBraveAdsIdleThreshold[] = "brave.brave_ads.idle_threshold"; +const int kBraveAdsPrefsDefaultVersion = 1; +const int kBraveAdsPrefsCurrentVersion = 2; +const char kBraveAdsPrefsVersion[] = "brave.brave_ads.prefs.version"; + } // namespace prefs + } // namespace brave_ads diff --git a/components/brave_ads/common/pref_names.h b/components/brave_ads/common/pref_names.h index ce4c7833185a..a6a5699ba78a 100644 --- a/components/brave_ads/common/pref_names.h +++ b/components/brave_ads/common/pref_names.h @@ -1,4 +1,5 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -6,14 +7,19 @@ #define BRAVE_COMPONENTS_BRAVE_ADS_COMMON_PREF_NAMES_H_ namespace brave_ads { + namespace prefs { extern const char kBraveAdsEnabled[]; extern const char kBraveAdsPerHour[]; extern const char kBraveAdsPerDay[]; extern const char kBraveAdsIdleThreshold[]; +extern const int kBraveAdsPrefsDefaultVersion; +extern const int kBraveAdsPrefsCurrentVersion; +extern const char kBraveAdsPrefsVersion[]; } // namespace prefs + } // namespace brave_ads #endif // BRAVE_COMPONENTS_BRAVE_ADS_COMMON_PREF_NAMES_H_ diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc index bad847d314cc..e7cea4776900 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc +++ b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc @@ -852,17 +852,10 @@ bool AdsImpl::IsAllowedToShowAds() { auto respects_hour_limit = HistoryRespectsRollingTimeConstraint( ads_shown_history, hour_window, hour_allowed); -#if 0 -/* - TBD: [MTR] LEAVE UNTIL DESIGN/PRODUCT RESOLVES THE USE OF THIS FEATURE - */ auto day_window = base::Time::kSecondsPerHour * base::Time::kHoursPerDay; auto day_allowed = ads_client_->GetAdsPerDay(); auto respects_day_limit = HistoryRespectsRollingTimeConstraint( ads_shown_history, day_window, day_allowed); -#else - auto respects_day_limit = true; -#endif auto minimum_wait_time = hour_window / hour_allowed; bool respects_minimum_wait_time = HistoryRespectsRollingTimeConstraint( @@ -1549,14 +1542,9 @@ void AdsImpl::GenerateAdReportingSettingsEvent() { auto locale = client_->GetLocale(); writer.String(locale.c_str()); -#if 0 -/* - TBD: [MTR] LEAVE UNTIL DESIGN/PRODUCT RESOLVES THE USE OF THIS FEATURE - */ writer.String("adsPerDay"); auto ads_per_day = ads_client_->GetAdsPerDay(); writer.Uint64(ads_per_day); -#endif writer.String("adsPerHour"); auto ads_per_hour = ads_client_->GetAdsPerHour();