Skip to content

Commit

Permalink
[ads] Add SmartNTT virtual skus pref
Browse files Browse the repository at this point in the history
  • Loading branch information
tmancey committed Oct 29, 2024
1 parent f66a262 commit 38afbf2
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 15 deletions.
1 change: 1 addition & 0 deletions browser/brave_ads/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
119 changes: 110 additions & 9 deletions browser/brave_ads/ads_service_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

#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"
Expand All @@ -15,6 +17,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"
Expand All @@ -34,6 +37,62 @@

namespace brave_ads {

namespace {

std::string NormalizeSkuEnvironment(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("created_at")) {
order.Set("created_at", *created_at);
}

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

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

if (const auto* const status = dict.FindString("status")) {
const std::string normalized_status = NormalizeSkuStatus(*status);
order.Set("status", 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("location");
if (!location) {
continue;
}

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

return orders;
}

} // namespace

AdsServiceDelegate::AdsServiceDelegate(
Profile* profile,
PrefService* local_state,
Expand Down Expand Up @@ -65,6 +124,39 @@ std::string AdsServiceDelegate::GetDefaultSearchEngineName() {
return base::UTF16ToUTF8(default_search_engine_name);
}

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

if (!local_state_->HasPrefPath(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("skus:")) {
continue;
}

// Convert to Value as it's stored as 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("orders");
if (!orders) {
continue;
}

skus.Set(NormalizeSkuEnvironment(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 @@ -158,15 +250,24 @@ 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]:build_channel.name",
version_info::GetChannelString(chrome::GetChannel()))
.Set("[virtual]:browser_version", version_info::GetVersionNumber())
.Set("[virtual]:default_search_engine.name",
GetDefaultSearchEngineName());
.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
2 changes: 2 additions & 0 deletions browser/brave_ads/ads_service_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
//
Expand Down Expand Up @@ -129,22 +129,41 @@ class PrefProviderInterface;
// local state prefs. Virtual pref path keys should be prefixed with
// "[virtual]:".
//
// "[virtual]:operating_system.name" retrieves the operating system, returning
// one of the following values: "Windows", "Mac OS X", "Linux", "Android",
// "iOS", or "Unknown".
// "[virtual]:browser_version" retrieves the browser version, e.g. "72.0.59.3".
//
// "[virtual]:build_channel.name" retrieves the build channel of the browser,
// returning one of the following values: "stable", "beta", "dev", "nightly", or
// "unknown".
//
// "[virtual]:browser_version" retrieves the browser version, e.g. "6.0.490.1".
// "[virtual]:operating_system.locale" retrieves the operating system locale,
// i.e., "en_US".
//
// "[virtual]:operating_system.name" retrieves the operating system, returning
// one of the following values: "Windows", "Mac OS X", "Linux", "Android",
// "iOS", or "Unknown".
//
// "[virtual]:default_search_engine.name" retrieves the default search engine
// "[virtual]:search_engine.default_name" retrieves the default search engine
// chosen during browser installation, returning one of the following values:
// "Brave", "Google", "Yandex", "Bing", "Daum", "네이버", "DuckDuckGo", "Qwant",
// "Startpage", or "Ecosia". For the most up-to-date list of possible default
// search engines, see `TemplateURLPrepopulateData::GetDefaultSearchEngine`.
//
// "[virtual]:skus" retrieves the SKUs for the browser, returning either
// `trial`, `beta`, `paid`, or `canceled` for status, i.e.,
//
// "production": {
// "talk.brave.com": {
// "created_at": "2023-05-05T12:26:57",
// "expires_at": "2024-05-04T13:44:55",
// "status": "paid"
// },
// "vpn.brave.com": {
// "created_at": "2023-02-23T21:49:34",
// "expires_at": "2024-09-24T21:49:57",
// "status": "canceled"
// }
// }
//
// NOTE: To identify condition matchers, first create a copy of your pref files.
// Next, change a brave://setting or enable a feature, quit the browser and then
// compare the original and modified versions to determine which key/value pairs
Expand Down

0 comments on commit 38afbf2

Please sign in to comment.