diff --git a/browser/brave_ads/BUILD.gn b/browser/brave_ads/BUILD.gn index f061e10f1e71..88c2ebee2dae 100644 --- a/browser/brave_ads/BUILD.gn +++ b/browser/brave_ads/BUILD.gn @@ -63,6 +63,7 @@ source_set("impl") { "//brave/components/brave_ads/browser/application_state", "//brave/components/l10n/common", "//brave/components/p3a_utils", + "//brave/components/skus/browser", "//chrome/browser:browser_process", "//chrome/browser:browser_public_dependencies", "//chrome/browser:primitives", diff --git a/browser/brave_ads/ads_service_delegate.cc b/browser/brave_ads/ads_service_delegate.cc index 2bb237dda2ba..58354f9aebbb 100644 --- a/browser/brave_ads/ads_service_delegate.cc +++ b/browser/brave_ads/ads_service_delegate.cc @@ -7,6 +7,7 @@ #include +#include "base/json/json_reader.h" #include "base/strings/utf_string_conversions.h" #include "base/version_info/channel.h" #include "base/version_info/version_info.h" @@ -15,6 +16,7 @@ #include "brave/browser/ui/brave_ads/notification_ad.h" #include "brave/components/brave_adaptive_captcha/brave_adaptive_captcha_service.h" #include "brave/components/l10n/common/locale_util.h" +#include "brave/components/skus/browser/pref_names.h" #include "build/build_config.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/profiles/profile.h" @@ -65,6 +67,68 @@ std::string AdsServiceDelegate::GetDefaultSearchEngineName() { return base::UTF16ToUTF8(default_search_engine_name); } +base::Value::Dict AdsServiceDelegate::GetSkus() const { + base::Value::Dict dict; + + const base::Value::Dict& skus_state_dict = + local_state_->GetDict(skus::prefs::kSkusState); + + for (const auto [environment, sku_state] : skus_state_dict) { + if (!environment.starts_with("skus:")) { + continue; + } + + // Convert to Value as it's stored as string in local state. + const std::optional sku_state_dict = + base::JSONReader::ReadDict(sku_state.GetString()); + if (!sku_state_dict) { + continue; + } + + const base::Value::Dict* const orders_dict = + sku_state_dict->FindDict("orders"); + if (!orders_dict) { + continue; + } + + base::Value::Dict sku_dict; + + for (const auto [_, order] : *orders_dict) { + const auto* order_dict = order.GetIfDict(); + if (!order_dict) { + continue; + } + + const std::string* const location = order_dict->FindString("location"); + if (!location) { + continue; + } + + base::Value::Dict location_dict; + + if (const auto* const created_at = order_dict->FindString("created_at")) { + location_dict.Set("created_at", *created_at); + } + + if (const auto* const expires_at = order_dict->FindString("expires_at")) { + location_dict.Set("expires_at", *expires_at); + } + + if (const auto* const status = order_dict->FindString("status")) { + location_dict.Set("status", *status); + } + + sku_dict.Set(*location, std::move(location_dict)); + } + + // Strip the environment prefix. + const size_t pos = environment.find(':'); + dict.Set(environment.substr(pos + 1), std::move(sku_dict)); + } + + return dict; +} + void AdsServiceDelegate::OpenNewTabWithUrl(const GURL& url) { #if BUILDFLAG(IS_ANDROID) // ServiceTabLauncher can currently only launch new tabs @@ -158,15 +222,14 @@ bool AdsServiceDelegate::IsFullScreenMode() { base::Value::Dict AdsServiceDelegate::GetVirtualPrefs() { return base::Value::Dict() - .Set("[virtual]:operating_system.name", version_info::GetOSType()) - .Set("[virtual]:operating_system.locale", - brave_l10n::GetDefaultLocaleString()) - .Set("[virtual]:application_locale", application_locale_) + .Set("[virtual]:browser.version", version_info::GetVersionNumber()) .Set("[virtual]:build_channel.name", version_info::GetChannelString(chrome::GetChannel())) - .Set("[virtual]:browser_version", version_info::GetVersionNumber()) - .Set("[virtual]:default_search_engine.name", - GetDefaultSearchEngineName()); + .Set("[virtual]:operating_system.locale", + brave_l10n::GetDefaultLocaleString()) + .Set("[virtual]:operating_system.name", version_info::GetOSType()) + .Set("[virtual]:search_engine.default_name", GetDefaultSearchEngineName()) + .Set("[virtual]:skus", GetSkus()); } } // namespace brave_ads diff --git a/browser/brave_ads/ads_service_delegate.h b/browser/brave_ads/ads_service_delegate.h index fafb671812c2..c2240d2e5ae0 100644 --- a/browser/brave_ads/ads_service_delegate.h +++ b/browser/brave_ads/ads_service_delegate.h @@ -49,6 +49,8 @@ class AdsServiceDelegate : public AdsService::Delegate { std::string GetDefaultSearchEngineName(); + base::Value::Dict GetSkus() const; + // AdsService::Delegate implementation void InitNotificationHelper() override; bool CanShowSystemNotificationsWhileBrowserIsBackgrounded() override; diff --git a/components/brave_ads/core/public/serving/targeting/condition_matcher/condition_matcher_util.h b/components/brave_ads/core/public/serving/targeting/condition_matcher/condition_matcher_util.h index fc1b6c4b0430..59c6c2c76783 100644 --- a/components/brave_ads/core/public/serving/targeting/condition_matcher/condition_matcher_util.h +++ b/components/brave_ads/core/public/serving/targeting/condition_matcher/condition_matcher_util.h @@ -65,7 +65,7 @@ class PrefProviderInterface; // - 'R≥': Greater than or equal to // - 'R<': Less than // - 'R≤': Less than or equal to -// - This matcher triggers an ad based on when a real number stored a1t +// - This matcher triggers an ad based on when a real number stored at // "prefPath". For instance, the example below will serve an ad only if the // value stored at "foo.bar" is not equal to 3: //