Skip to content

Commit

Permalink
Merge pull request #26284 from brave/issues/41927
Browse files Browse the repository at this point in the history
[ads] Add SmartNTT virtual prefs and condition matchers
  • Loading branch information
tmancey authored Oct 30, 2024
2 parents 7385f23 + 2b44a7f commit f98f048
Show file tree
Hide file tree
Showing 72 changed files with 2,199 additions and 1,256 deletions.
2 changes: 2 additions & 0 deletions browser/brave_ads/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ source_set("impl") {
"//brave/browser/ui/brave_ads",
"//brave/components/brave_adaptive_captcha",
"//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",
Expand Down
142 changes: 131 additions & 11 deletions browser/brave_ads/ads_service_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@

#include "brave/browser/brave_ads/ads_service_delegate.h"

#include <cstddef>
#include <utility>

#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"
#include "brave/browser/brave_ads/ad_units/notification_ad/notification_ad_platform_bridge.h"
#include "brave/browser/brave_ads/application_state/notification_helper/notification_helper.h"
#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"
Expand All @@ -32,6 +37,71 @@

namespace brave_ads {

namespace {

constexpr char kSkuEnvironmentPrefix[] = "skus:";
constexpr char kSkuOrdersKey[] = "orders";
constexpr char kSkuOrderLocationKey[] = "location";
constexpr char kSkuOrderCreatedAtKey[] = "created_at";
constexpr char kSkuOrderExpiresAtKey[] = "expires_at";
constexpr char kSkuOrderLastPaidAtKey[] = "last_paid_at";
constexpr char kSkuOrderStatusKey[] = "status";

std::string StripSkuEnvironmentPrefix(const std::string& environment) {
const size_t pos = environment.find(':');
return environment.substr(pos + 1);
}

std::string NormalizeSkuStatus(const std::string& status) {
return status == "cancelled" ? "canceled" : status;
}

base::Value::Dict ParseSkuOrder(const base::Value::Dict& dict) {
base::Value::Dict order;

if (const auto* const created_at = dict.FindString(kSkuOrderCreatedAtKey)) {
order.Set(kSkuOrderCreatedAtKey, *created_at);
}

if (const auto* const expires_at = dict.FindString(kSkuOrderExpiresAtKey)) {
order.Set(kSkuOrderExpiresAtKey, *expires_at);
}

if (const auto* const last_paid_at =
dict.FindString(kSkuOrderLastPaidAtKey)) {
order.Set(kSkuOrderLastPaidAtKey, *last_paid_at);
}

if (const auto* const status = dict.FindString(kSkuOrderStatusKey)) {
const std::string normalized_status = NormalizeSkuStatus(*status);
order.Set(kSkuOrderStatusKey, normalized_status);
}

return order;
}

base::Value::Dict ParseSkuOrders(const base::Value::Dict& dict) {
base::Value::Dict orders;

for (const auto [/*id*/ _, value] : dict) {
const base::Value::Dict* const order = value.GetIfDict();
if (!order) {
continue;
}

const std::string* const location = order->FindString(kSkuOrderLocationKey);
if (!location) {
continue;
}

orders.Set(*location, ParseSkuOrder(*order));
}

return orders;
}

} // namespace

AdsServiceDelegate::AdsServiceDelegate(
Profile* profile,
PrefService* local_state,
Expand All @@ -53,6 +123,49 @@ AdsServiceDelegate::AdsServiceDelegate(

AdsServiceDelegate::~AdsServiceDelegate() {}

std::string AdsServiceDelegate::GetDefaultSearchEngineName() {
const auto template_url_data =
TemplateURLPrepopulateData::GetPrepopulatedFallbackSearch(
profile_->GetPrefs(), &search_engine_choice_service_);

const std::u16string& default_search_engine_name =
template_url_data ? template_url_data->short_name() : u"";
return base::UTF16ToUTF8(default_search_engine_name);
}

base::Value::Dict AdsServiceDelegate::GetSkus() const {
base::Value::Dict skus;

if (!local_state_->FindPreference(skus::prefs::kSkusState)) {
// No SKUs in local state.
return skus;
}

const base::Value::Dict& skus_state =
local_state_->GetDict(skus::prefs::kSkusState);
for (const auto [environment, value] : skus_state) {
if (!environment.starts_with(kSkuEnvironmentPrefix)) {
continue;
}

// Parse the SKUs JSON because it is stored as a string in local state.
const std::optional<base::Value::Dict> sku_state =
base::JSONReader::ReadDict(value.GetString());
if (!sku_state) {
continue;
}

const base::Value::Dict* const orders = sku_state->FindDict(kSkuOrdersKey);
if (!orders) {
continue;
}

skus.Set(StripSkuEnvironmentPrefix(environment), ParseSkuOrders(*orders));
}

return skus;
}

void AdsServiceDelegate::OpenNewTabWithUrl(const GURL& url) {
#if BUILDFLAG(IS_ANDROID)
// ServiceTabLauncher can currently only launch new tabs
Expand Down Expand Up @@ -145,18 +258,25 @@ bool AdsServiceDelegate::IsFullScreenMode() {
#endif

base::Value::Dict AdsServiceDelegate::GetVirtualPrefs() {
const auto template_url_data =
TemplateURLPrepopulateData::GetPrepopulatedFallbackSearch(
profile_->GetPrefs(), &search_engine_choice_service_);
if (!template_url_data) {
return {};
}

return base::Value::Dict()
.Set("[virtual]:default_search_engine.name",
base::UTF16ToUTF8(template_url_data->short_name()))
.Set("[virtual]:build_channel.name",
version_info::GetChannelString(chrome::GetChannel()));
.Set("[virtual]:browser",
base::Value::Dict()
.Set("build_channel",
version_info::GetChannelString(chrome::GetChannel()))
.Set("version", version_info::GetVersionNumber()))
.Set("[virtual]:operating_system",
base::Value::Dict()
.Set("locale",
base::Value::Dict()
.Set("language",
brave_l10n::GetDefaultISOLanguageCodeString())
.Set("region",
brave_l10n::GetDefaultISOCountryCodeString()))
.Set("name", version_info::GetOSType()))
.Set(
"[virtual]:search_engine",
base::Value::Dict().Set("default_name", GetDefaultSearchEngineName()))
.Set("[virtual]:skus", GetSkus());
}

} // namespace brave_ads
4 changes: 4 additions & 0 deletions browser/brave_ads/ads_service_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class AdsServiceDelegate : public AdsService::Delegate {

~AdsServiceDelegate() override;

std::string GetDefaultSearchEngineName();

base::Value::Dict GetSkus() const;

// AdsService::Delegate implementation
void InitNotificationHelper() override;
bool CanShowSystemNotificationsWhileBrowserIsBackgrounded() override;
Expand Down
24 changes: 19 additions & 5 deletions components/brave_ads/core/internal/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -617,8 +617,8 @@ static_library("internal") {
"diagnostics/entries/diagnostic_entry_interface.h",
"diagnostics/entries/last_unidle_time_diagnostic_entry.cc",
"diagnostics/entries/last_unidle_time_diagnostic_entry.h",
"diagnostics/entries/last_unidle_time_diagnostic_util.cc",
"diagnostics/entries/last_unidle_time_diagnostic_util.h",
"diagnostics/entries/last_unidle_time_diagnostic_entry_util.cc",
"diagnostics/entries/last_unidle_time_diagnostic_entry_util.h",
"diagnostics/entries/locale_diagnostic_entry.cc",
"diagnostics/entries/locale_diagnostic_entry.h",
"diagnostics/entries/opted_into_brave_news_ads_diagnostic_entry.cc",
Expand Down Expand Up @@ -834,9 +834,6 @@ static_library("internal") {
"serving/inline_content_ad_serving_feature.h",
"serving/new_tab_page_ad_serving.cc",
"serving/new_tab_page_ad_serving.h",
"serving/new_tab_page_ad_serving_condition_matcher_util.cc",
"serving/new_tab_page_ad_serving_condition_matcher_util_internal.cc",
"serving/new_tab_page_ad_serving_condition_matcher_util_internal.h",
"serving/new_tab_page_ad_serving_delegate.h",
"serving/new_tab_page_ad_serving_feature.cc",
"serving/new_tab_page_ad_serving_feature.h",
Expand Down Expand Up @@ -941,6 +938,23 @@ static_library("internal") {
"serving/prediction/model_based/weight/creative_notification_ad_model_based_predictor_weights_builder.cc",
"serving/prediction/model_based/weight/creative_notification_ad_model_based_predictor_weights_builder.h",
"serving/prediction/model_based/weight/segment/creative_ad_model_based_predictor_segment_weight_info.h",
"serving/targeting/condition_matcher/condition_matcher_util.cc",
"serving/targeting/condition_matcher/matchers/epoch_operator_condition_matcher_util.cc",
"serving/targeting/condition_matcher/matchers/epoch_operator_condition_matcher_util.h",
"serving/targeting/condition_matcher/matchers/internal/epoch_operator_condition_matcher_util_internal.cc",
"serving/targeting/condition_matcher/matchers/internal/epoch_operator_condition_matcher_util_internal.h",
"serving/targeting/condition_matcher/matchers/internal/numerical_operator_condition_matcher_util_internal.cc",
"serving/targeting/condition_matcher/matchers/internal/numerical_operator_condition_matcher_util_internal.h",
"serving/targeting/condition_matcher/matchers/numerical_operator_condition_matcher_util.cc",
"serving/targeting/condition_matcher/matchers/numerical_operator_condition_matcher_util.h",
"serving/targeting/condition_matcher/matchers/pattern_condition_matcher_util.cc",
"serving/targeting/condition_matcher/matchers/pattern_condition_matcher_util.h",
"serving/targeting/condition_matcher/matchers/regex_condition_matcher_util.cc",
"serving/targeting/condition_matcher/matchers/regex_condition_matcher_util.h",
"serving/targeting/condition_matcher/prefs/condition_matcher_pref_util.cc",
"serving/targeting/condition_matcher/prefs/condition_matcher_pref_util.h",
"serving/targeting/condition_matcher/prefs/internal/condition_matcher_pref_util_internal.cc",
"serving/targeting/condition_matcher/prefs/internal/condition_matcher_pref_util_internal.h",
"serving/targeting/segments/top_segments.cc",
"serving/targeting/segments/top_segments.h",
"serving/targeting/segments/top_user_model_segments.cc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ TEST_F(BraveAdsAccountTest, DepositForCash) {
EXPECT_CALL(account_observer_mock_,
OnDidProcessDeposit(/*transaction=*/::testing::FieldsAre(
/*id*/ ::testing::_, /*created_at*/ test::Now(),
test::kCreativeInstanceId, test::kSegment, /*value*/ 1.0,
test::kCreativeInstanceId, test::kSegment, test::kValue,
mojom::AdType::kNotificationAd,
mojom::ConfirmationType::kViewedImpression,
/*reconciled_at*/ std::nullopt)));
Expand Down Expand Up @@ -251,7 +251,7 @@ TEST_F(BraveAdsAccountTest, DepositForCashWithUserData) {
EXPECT_CALL(account_observer_mock_,
OnDidProcessDeposit(/*transaction=*/::testing::FieldsAre(
/*id*/ ::testing::_, /*created_at*/ test::Now(),
test::kCreativeInstanceId, test::kSegment, /*value*/ 1.0,
test::kCreativeInstanceId, test::kSegment, test::kValue,
mojom::AdType::kNotificationAd,
mojom::ConfirmationType::kViewedImpression,
/*reconciled_at*/ std::nullopt)));
Expand Down Expand Up @@ -330,7 +330,7 @@ TEST_F(BraveAdsAccountTest, AddTransactionWhenDepositingCashForRewardsUser) {
EXPECT_CALL(account_observer_mock_,
OnDidProcessDeposit(/*transaction=*/::testing::FieldsAre(
/*id*/ ::testing::_, /*created_at*/ test::Now(),
test::kCreativeInstanceId, test::kSegment, /*value*/ 1.0,
test::kCreativeInstanceId, test::kSegment, test::kValue,
mojom::AdType::kNotificationAd,
mojom::ConfirmationType::kViewedImpression,
/*reconciled_at*/ std::nullopt)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ std::optional<std::string> WriteRewardCredential(
}

const std::optional<base::Value::Dict> credential =
cbr::BuildCredential(reward->unblinded_token, payload);
cbr::MaybeBuildCredential(reward->unblinded_token, payload);
if (!credential) {
return std::nullopt;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ TEST_F(BraveAdsCashDepositIntegrationTest, GetValue) {

// Act & Assert
base::MockCallback<GetDepositCallback> callback;
EXPECT_CALL(callback, Run(/*success=*/true, /*value=*/1.0));
EXPECT_CALL(callback, Run(/*success=*/true, test::kValue));
deposit.GetValue(test::kCreativeInstanceId, callback.Get());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ base::Value::List RedeemPaymentTokensUrlRequestBuilder::BuildPaymentRequestDTO(

for (const auto& payment_token : payment_tokens_) {
std::optional<base::Value::Dict> credential =
cbr::BuildCredential(payment_token.unblinded_token, payload);
cbr::MaybeBuildCredential(payment_token.unblinded_token, payload);
if (!credential) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ inline constexpr char kTargetUrl[] = "https://brave.com";
inline constexpr char kTitle[] = "Test Ad Title";
inline constexpr char kDescription[] = "Test Ad Description";

inline constexpr int kValue = 1.0;
inline constexpr double kValue = 1.0;

} // namespace brave_ads::test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <vector>

#include "brave/components/brave_ads/core/internal/catalog/campaign/creative_set/creative/new_tab_page_ad/catalog_new_tab_page_ad_wallpaper_focal_point_info.h"
#include "brave/components/brave_ads/core/public/serving/new_tab_page_ad_serving_condition_matcher_util.h"
#include "brave/components/brave_ads/core/public/serving/targeting/condition_matcher/condition_matcher_util.h"
#include "url/gurl.h"

namespace brave_ads {
Expand All @@ -31,7 +31,7 @@ struct CatalogNewTabPageAdWallpaperInfo final {

GURL image_url;
CatalogNewTabPageAdWallpaperFocalPointInfo focal_point;
NewTabPageAdConditionMatchers condition_matchers;
ConditionMatcherMap condition_matchers;
};

using CatalogNewTabPageAdWallpaperList =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ constexpr char kTokenPreimageKey[] = "t";

} // namespace

std::optional<base::Value::Dict> BuildCredential(
std::optional<base::Value::Dict> MaybeBuildCredential(
const UnblindedToken& unblinded_token,
const std::string& payload) {
CHECK(unblinded_token.has_value());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace brave_ads::cbr {

class UnblindedToken;

std::optional<base::Value::Dict> BuildCredential(
std::optional<base::Value::Dict> MaybeBuildCredential(
const UnblindedToken& unblinded_token,
const std::string& payload);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace brave_ads {

TEST(BraveAdsChallengeBypassRistrettoTest, BuildCredential) {
// Act
const std::optional<base::Value::Dict> credential = cbr::BuildCredential(
const std::optional<base::Value::Dict> credential = cbr::MaybeBuildCredential(
cbr::UnblindedToken(cbr::test::kUnblindedTokenBase64),
/*payload=*/"definition: the weight of a payload");
ASSERT_TRUE(credential);
Expand Down
2 changes: 1 addition & 1 deletion components/brave_ads/core/internal/common/test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ See [command_line_switch_test_util.h](command_line_switch_test_util.h).

## Mocking Prefs

Preferences **MUST** be registered in [pref_registry_test_util.cc](./pref_registry_test_util.cc). To set a preference and notify listeners, use `SetProfile*Pref` or `SetLocalState*Pref`. To set a preference without notifying listeners, use `SetProfile*PrefValue` or `SetLocalState*PrefValue`. See [profile_pref_value_test_util.h](./profile_pref_value_test_util.h) and [local_state_pref_value_test_util.h](./local_state_pref_value_test_util.h).
You can register preferences in [pref_registry_test_util.cc](./pref_registry_test_util.cc) or by using `RegisterProfile*Pref` or `RegisterLocalState*Pref`. To set a preference and notify listeners, use `SetProfile*Pref` or `SetLocalState*Pref`. To set a preference without notifying listeners, use `SetProfile*PrefValue` or `SetLocalState*PrefValue`. See [profile_pref_value_test_util.h](./profile_pref_value_test_util.h) and [local_state_pref_value_test_util.h](./local_state_pref_value_test_util.h).

## Mocking Files

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "brave/components/brave_ads/core/internal/common/test/internal/local_state_pref_registry_test_util_internal.h"
#include "brave/components/brave_ads/core/internal/common/test/local_state_pref_registry_test_util.h"

#include <utility>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_INTERNAL_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_INTERNAL_H_
#define BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_INTERNAL_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_INTERNAL_H_
#ifndef BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_H_
#define BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_H_

#include <cstdint>
#include <string>
Expand Down Expand Up @@ -40,4 +40,4 @@ void RegisterLocalStateTimeDeltaPref(const std::string& path,

} // namespace brave_ads::test

#endif // BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_INTERNAL_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_INTERNAL_H_
#endif // BRAVE_COMPONENTS_BRAVE_ADS_CORE_INTERNAL_COMMON_TEST_LOCAL_STATE_PREF_REGISTRY_TEST_UTIL_H_
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include "brave/components/brave_ads/core/internal/common/test/pref_registry_test_util.h"

#include "base/time/time.h"
#include "brave/components/brave_ads/core/internal/common/test/internal/local_state_pref_registry_test_util_internal.h"
#include "brave/components/brave_ads/core/internal/common/test/internal/profile_pref_registry_test_util_internal.h"
#include "brave/components/brave_ads/core/internal/common/test/local_state_pref_registry_test_util.h"
#include "brave/components/brave_ads/core/internal/common/test/profile_pref_registry_test_util.h"
#include "brave/components/brave_ads/core/internal/common/test/time_test_util.h"
#include "brave/components/brave_ads/core/public/prefs/pref_names.h"
#include "brave/components/brave_news/common/pref_names.h"
Expand Down
Loading

0 comments on commit f98f048

Please sign in to comment.