Add metric configuration and alternative metric attributes

This commit is contained in:
Darnell Andries
2024-12-19 13:36:53 -08:00
parent d5f66860de
commit 8bea824f88
19 changed files with 1003 additions and 424 deletions
@@ -56,6 +56,22 @@ std::string GetPlatformIdentifier() {
#endif
}
std::string GetGeneralPlatformIdentifier() {
#if BUILDFLAG(IS_WIN)
return "windows";
#elif BUILDFLAG(IS_MAC)
return "macos";
#elif BUILDFLAG(IS_LINUX)
return "linux";
#elif BUILDFLAG(IS_IOS)
return "ios";
#elif BUILDFLAG(IS_ANDROID)
return "android";
#else
return std::string();
#endif
}
int GetIsoWeekNumber(const base::Time& time) {
char buffer[24];
time_t rawtime = time.ToTimeT();
@@ -24,6 +24,8 @@ std::string GetDateAsYMD(const base::Time& time);
std::string GetPlatformIdentifier();
std::string GetGeneralPlatformIdentifier();
int GetIsoWeekNumber(const base::Time& time);
base::Time GetLastMondayTime(const base::Time& time);
+4
View File
@@ -24,6 +24,7 @@ static_library("p3a") {
"histograms_braveizer.h",
"message_manager.cc",
"message_manager.h",
"metric_config.h",
"metric_log_store.cc",
"metric_log_store.h",
"metric_log_type.cc",
@@ -44,6 +45,8 @@ static_library("p3a") {
"p3a_service.cc",
"p3a_service.h",
"pref_names.h",
"region.cc",
"region.h",
"rotation_scheduler.cc",
"rotation_scheduler.h",
"scheduler.cc",
@@ -100,6 +103,7 @@ source_set("unit_tests") {
"nitro_utils/cose_unittest.cc",
"p2a_protocols_unittest.cc",
"p3a_service_unittest.cc",
"region_unittest.cc",
"rotation_scheduler_unittest.cc",
"scheduler_unittest.cc",
"star_randomness_test_util.cc",
@@ -16,6 +16,7 @@
#include "base/strings/string_util.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "brave/components/p3a/metric_config.h"
#include "brave/components/p3a/metric_log_type.h"
#include "brave/components/p3a/p3a_config.h"
#include "brave/components/p3a/p3a_message.h"
@@ -255,8 +256,8 @@ TEST_F(P3AConstellationHelperTest, GenerateBasicMessage) {
helper_->StartMessagePreparation(
kTestHistogramName, log_type,
GenerateP3AConstellationMessage(kTestHistogramName, test_epoch,
meta_info, kP3AUploadType, false,
false),
meta_info, kP3AUploadType,
std::nullopt),
false);
task_environment_.RunUntilIdle();
@@ -276,7 +277,7 @@ TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
meta_info.Init(&local_state_, "release", "2022-01-01");
std::string message_with_no_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, false, false);
kTestHistogramName, 0, meta_info, kP3AUploadType, std::nullopt);
std::vector<std::string> no_refcode_layers = base::SplitString(
message_with_no_refcode, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -286,7 +287,8 @@ TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
EXPECT_FALSE(no_refcode_layers.at(7).starts_with("ref"));
std::string message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true, false);
kTestHistogramName, 0, meta_info, kP3AUploadType,
MetricConfig{.append_attributes = {MetricAttribute::kRef}});
std::vector<std::string> refcode_layers = base::SplitString(
message_with_refcode, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -300,7 +302,8 @@ TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
meta_info.Init(&local_state_, "release", "2022-01-01");
message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true, false);
kTestHistogramName, 0, meta_info, kP3AUploadType,
MetricConfig{.append_attributes = {MetricAttribute::kRef}});
refcode_layers = base::SplitString(message_with_refcode,
kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -313,7 +316,8 @@ TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
meta_info.Init(&local_state_, "release", "2022-01-01");
message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true, false);
kTestHistogramName, 0, meta_info, kP3AUploadType,
MetricConfig{.append_attributes = {MetricAttribute::kRef}});
refcode_layers = base::SplitString(message_with_refcode,
kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -324,12 +328,53 @@ TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
#endif // !BUILDFLAG(IS_IOS)
}
TEST_F(P3AConstellationHelperTest, CustomAttributes) {
MessageMetainfo meta_info;
meta_info.Init(&local_state_, "release", "2022-01-01");
// Test with custom attributes list
MetricConfig config{.attributes = MetricAttributes{
MetricAttribute::kAnswerIndex,
MetricAttribute::kVersion,
MetricAttribute::kPlatform,
MetricAttribute::kGeneralPlatform,
MetricAttribute::kChannel,
MetricAttribute::kRegion,
MetricAttribute::kSubregion,
}};
std::string message = GenerateP3AConstellationMessage(
kTestHistogramName, 7, meta_info, kP3AUploadType, config);
std::vector<std::string> layers =
base::SplitString(message, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
base::SplitResult::SPLIT_WANT_NONEMPTY);
// Verify number of layers matches number of non-null attributes
EXPECT_EQ(layers.size(), 8U);
// Verify each layer's content
EXPECT_EQ(layers[0], base::StrCat({"metric_name|", kTestHistogramName}));
EXPECT_EQ(layers[1], "metric_value|7");
EXPECT_EQ(layers[2], "version|" + meta_info.version());
EXPECT_EQ(layers[3], "platform|" + meta_info.platform());
EXPECT_EQ(layers[4], "general_platform|" + meta_info.general_platform());
EXPECT_EQ(layers[5], "channel|release");
EXPECT_EQ(layers[6],
base::StrCat({"region|", meta_info.region_identifiers().region}));
EXPECT_EQ(
layers[7],
base::StrCat({"subregion|", meta_info.region_identifiers().sub_region}));
}
TEST_F(P3AConstellationHelperTest, NebulaMessage) {
MessageMetainfo meta_info;
meta_info.Init(&local_state_, "release", "2022-01-01");
std::string message = GenerateP3AConstellationMessage(
kTestHistogramName, 3, meta_info, kP3AUploadType, false, true);
kTestHistogramName, 3, meta_info, kP3AUploadType,
MetricConfig{.nebula = true});
std::vector<std::string> no_refcode_layers =
base::SplitString(message, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -355,7 +400,7 @@ TEST_F(P3AConstellationHelperTest, NebulaSample) {
kTestNebulaHistogramName, MetricLogType::kTypical,
GenerateP3AConstellationMessage(kTestNebulaHistogramName,
kTestTypicalEpoch, meta_info,
kP3AUploadType, false, true),
kP3AUploadType, std::nullopt),
true);
task_environment_.RunUntilIdle();
+33 -14
View File
@@ -311,11 +311,12 @@ void MessageManager::StartScheduledUpload(bool is_constellation,
is_constellation
? constellation_send_log_stores_[log_type]->staged_log_type()
: json_log_stores_[log_type]->staged_log_type();
const bool is_nebula = is_constellation
? p3a::kNebulaOnlyHistograms.contains(
constellation_send_log_stores_[log_type]
->staged_log_histogram_name())
: false;
bool is_nebula = false;
if (is_constellation) {
const auto* metric_config = GetMetricConfig(
constellation_send_log_stores_[log_type]->staged_log_histogram_name());
is_nebula = metric_config && *metric_config && (*metric_config)->nebula;
}
VLOG(2) << logging_prefix << " - Uploading " << log.size() << " bytes";
uploader_->UploadLog(log, upload_type, is_constellation, is_nebula, log_type);
@@ -352,9 +353,10 @@ void MessageManager::StartScheduledConstellationPrep(MetricLogType log_type) {
const std::string log_key = log_store->staged_log_key();
VLOG(2) << "MessageManager::StartScheduledConstellationPrep - Requesting "
"randomness for histogram: "
<< log_key;
<< log_key << " " << log;
const bool is_nebula = p3a::kNebulaOnlyHistograms.contains(log_key);
const auto* metric_config = GetMetricConfig(log_key);
bool is_nebula = metric_config && *metric_config && (*metric_config)->nebula;
if (is_nebula && !features::IsNebulaEnabled()) {
// Do not report if Nebula feature is not enabled,
// mark request as successful to avoid transmission.
@@ -394,12 +396,10 @@ std::string MessageManager::SerializeLog(std::string_view histogram_name,
message_meta_.Update();
if (is_constellation) {
const bool include_refcode =
p3a::kHistogramsWithRefcodeIncluded.contains(histogram_name);
const bool is_nebula = p3a::kNebulaOnlyHistograms.contains(histogram_name);
return GenerateP3AConstellationMessage(histogram_name, value, message_meta_,
upload_type, include_refcode,
is_nebula);
const auto* metric_config = GetMetricConfig(histogram_name);
return GenerateP3AConstellationMessage(
histogram_name, value, message_meta_, upload_type,
metric_config ? *metric_config : std::nullopt);
} else {
base::Value::Dict p3a_json_value = GenerateP3AMessageDict(
histogram_name, value, log_type, message_meta_, upload_type);
@@ -411,6 +411,23 @@ std::string MessageManager::SerializeLog(std::string_view histogram_name,
}
}
const std::optional<MetricConfig>* MessageManager::GetMetricConfig(
const std::string_view histogram_name) const {
const std::optional<MetricConfig>* metric_config = nullptr;
auto it = p3a::kCollectedTypicalHistograms.find(histogram_name);
if (it != p3a::kCollectedTypicalHistograms.end()) {
metric_config = &it->second;
} else if (it = p3a::kCollectedSlowHistograms.find(histogram_name);
it != p3a::kCollectedSlowHistograms.end()) {
metric_config = &it->second;
} else if (it = p3a::kCollectedExpressHistograms.find(histogram_name);
it != p3a::kCollectedExpressHistograms.end()) {
metric_config = &it->second;
}
return metric_config;
}
bool MessageManager::IsActualMetric(const std::string& histogram_name) const {
return p3a::kCollectedTypicalHistograms.contains(histogram_name) ||
p3a::kCollectedExpressHistograms.contains(histogram_name) ||
@@ -420,7 +437,9 @@ bool MessageManager::IsActualMetric(const std::string& histogram_name) const {
bool MessageManager::IsEphemeralMetric(
const std::string& histogram_name) const {
return p3a::kEphemeralHistograms.contains(histogram_name) ||
const auto* metric_config = GetMetricConfig(histogram_name);
return (metric_config && *metric_config && (*metric_config)->ephemeral) ||
delegate_->GetDynamicMetricLogType(histogram_name).has_value();
}
+3
View File
@@ -88,6 +88,9 @@ class MessageManager : public MetricLogStore::Delegate {
std::string_view histogram_name,
std::optional<bool> only_update_for_constellation = std::nullopt);
const std::optional<MetricConfig>* GetMetricConfig(
const std::string_view histogram_name) const;
private:
void StartScheduledUpload(bool is_constellation, MetricLogType log_type);
void StartScheduledConstellationPrep(MetricLogType log_type);
+14 -14
View File
@@ -188,38 +188,38 @@ class P3AMessageManagerTest : public testing::Test,
std::vector<std::string> GetTestHistogramNames(MetricLogType log_type,
size_t p3a_count,
size_t p2a_count) {
auto histogram_names_begin = kCollectedExpressHistograms.cbegin();
auto histogram_names_end = kCollectedExpressHistograms.cend();
auto histograms_begin = kCollectedExpressHistograms.cbegin();
auto histograms_end = kCollectedExpressHistograms.cend();
std::vector<std::string> result;
size_t p3a_i = 0;
size_t p2a_i = 0;
switch (log_type) {
case MetricLogType::kExpress:
histogram_names_begin = kCollectedExpressHistograms.cbegin();
histogram_names_end = kCollectedExpressHistograms.cend();
histograms_begin = kCollectedExpressHistograms.cbegin();
histograms_end = kCollectedExpressHistograms.cend();
break;
case MetricLogType::kSlow:
histogram_names_begin = kCollectedSlowHistograms.cbegin();
histogram_names_end = kCollectedSlowHistograms.cend();
histograms_begin = kCollectedSlowHistograms.cbegin();
histograms_end = kCollectedSlowHistograms.cend();
break;
case MetricLogType::kTypical:
histogram_names_begin = kCollectedTypicalHistograms.cbegin();
histogram_names_end = kCollectedTypicalHistograms.cend();
histograms_begin = kCollectedTypicalHistograms.cbegin();
histograms_end = kCollectedTypicalHistograms.cend();
break;
default:
NOTREACHED();
}
for (auto histogram_name_i = histogram_names_begin;
histogram_name_i != histogram_names_end; histogram_name_i++) {
if (histogram_name_i->rfind(kP2APrefix, 0) == 0) {
for (auto histogram_i = histograms_begin; histogram_i != histograms_end;
histogram_i++) {
if (histogram_i->first.rfind(kP2APrefix, 0) == 0) {
if (p2a_i < p2a_count) {
result.push_back(std::string(*histogram_name_i));
result.push_back(std::string(histogram_i->first));
p2a_i++;
}
} else if (p3a_i < p3a_count &&
(histogram_name_i->starts_with("Brave.Core") ||
(histogram_i->first.starts_with("Brave.Core") ||
log_type == MetricLogType::kExpress)) {
result.push_back(std::string(*histogram_name_i));
result.push_back(std::string(histogram_i->first));
p3a_i++;
}
+60
View File
@@ -0,0 +1,60 @@
/* Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_COMPONENTS_P3A_METRIC_CONFIG_H_
#define BRAVE_COMPONENTS_P3A_METRIC_CONFIG_H_
#include <array>
#include <optional>
namespace p3a {
enum class MetricAttribute {
// Default attributes
kAnswerIndex,
kVersion,
kYoi,
kChannel,
kPlatform,
kCountryCode,
kWoi,
// Alternative attributes
kGeneralPlatform,
kRegion,
kSubregion,
kRef,
kMaxValue = kRef,
};
inline constexpr MetricAttribute kDefaultMetricAttributes[] = {
MetricAttribute::kAnswerIndex, MetricAttribute::kVersion,
MetricAttribute::kYoi, MetricAttribute::kChannel,
MetricAttribute::kPlatform, MetricAttribute::kCountryCode,
MetricAttribute::kWoi,
};
using MetricAttributes = std::array<std::optional<MetricAttribute>, 8>;
using MetricAttributesToAppend = std::array<std::optional<MetricAttribute>, 2>;
struct MetricConfig {
// Once the metric value has been sent, the value will be removed from the log
// store
bool ephemeral;
// Should only be sent via Constellation
bool constellation_only;
// Should only be sent via Nebula
bool nebula;
// Avoid reporting "other" for countries not included in the allowlist
// and rely on STAR to provide k-anonymity
bool disable_country_strip;
// Ordered attributes to be included with the metric
std::optional<MetricAttributes> attributes;
// Ordered attributes to be appended to the list of default attributes
MetricAttributesToAppend append_attributes;
};
} // namespace p3a
#endif // BRAVE_COMPONENTS_P3A_METRIC_CONFIG_H_
+1 -1
View File
@@ -56,7 +56,7 @@ class P3AMetricLogStoreTest : public testing::Test,
for (size_t i = 1; i <= message_count &&
histogram_it != p3a::kCollectedTypicalHistograms.end();
i++) {
log_store->UpdateValue(std::string(*histogram_it), 2);
log_store->UpdateValue(std::string(histogram_it->first), 2);
histogram_it++;
}
}
-1
View File
@@ -9,7 +9,6 @@
#include <optional>
#include <string>
namespace p3a {
inline constexpr char kCreativeMetricPrefix[] = "creativeInstanceId.";
+224 -314
View File
@@ -8,7 +8,8 @@
#include <string_view>
#include "base/containers/fixed_flat_set.h"
#include "base/containers/fixed_flat_map.h"
#include "brave/components/p3a/metric_config.h"
namespace p3a {
@@ -24,331 +25,240 @@ namespace p3a {
//
// clang-format off
inline constexpr auto kCollectedTypicalHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.AIChat.AcquisitionSource",
"Brave.AIChat.AvgPromptCount",
"Brave.AIChat.ChatCount",
"Brave.AIChat.ChatCount.Nebula",
"Brave.AIChat.ContextMenu.FreeUsages",
"Brave.AIChat.ContextMenu.MostUsedAction",
"Brave.AIChat.ContextMenu.PremiumUsages",
"Brave.AIChat.Enabled.2",
"Brave.AIChat.Enabled.SidebarEnabledA",
"Brave.AIChat.MostUsedEntryPoint",
"Brave.AIChat.NewUserReturning",
"Brave.AIChat.OmniboxOpens",
"Brave.AIChat.OmniboxWeekCompare",
"Brave.AIChat.UsageWeekly",
"Brave.AIChat.UsageWeekly.SidebarEnabledA",
"Brave.Ads.ClearData",
"Brave.Core.BookmarkCount",
"Brave.Core.CrashReportsEnabled",
"Brave.Core.DomainsLoaded",
"Brave.Core.FailedHTTPSUpgrades.2",
"Brave.Core.FirstPageLoadTime",
"Brave.Core.IsDefault",
"Brave.Core.NumberOfExtensions",
"Brave.Core.PagesReloaded",
"Brave.Core.TabCount",
"Brave.Core.WeeklyUsage",
"Brave.Core.WeeklyUsage.Nebula",
"Brave.Core.WindowCount.2",
"Brave.DNS.AutoSecureRequests.2",
"Brave.DNS.AutoSecureRequests.Cloudflare.2",
"Brave.DNS.AutoSecureRequests.Quad9.2",
"Brave.DNS.AutoSecureRequests.Wikimedia.2",
"Brave.DNS.SecureSetting",
"Brave.Extensions.AdBlock",
"Brave.IOS.IsLikelyDefault",
base::MakeFixedFlatMap<std::string_view, std::optional<MetricConfig>>({
{"Brave.AIChat.AcquisitionSource", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.AvgPromptCount", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.ChatCount", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.ChatCount.Nebula", MetricConfig{.nebula = true}},
{"Brave.AIChat.ContextMenu.FreeUsages", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.ContextMenu.MostUsedAction", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.ContextMenu.PremiumUsages", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.Enabled.2", {}},
{"Brave.AIChat.Enabled.SidebarEnabledA", {}},
{"Brave.AIChat.MostUsedEntryPoint", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.NewUserReturning", {}},
{"Brave.AIChat.OmniboxOpens", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.OmniboxWeekCompare", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.UsageWeekly", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.UsageWeekly.SidebarEnabledA", MetricConfig{.ephemeral = true}},
{"Brave.Ads.ClearData", MetricConfig{.ephemeral = true}},
{"Brave.Core.BookmarkCount", {}},
{"Brave.Core.CrashReportsEnabled", {}},
{"Brave.Core.DomainsLoaded", {}},
{"Brave.Core.FailedHTTPSUpgrades.2", MetricConfig{.ephemeral = true}},
{"Brave.Core.FirstPageLoadTime", MetricConfig{.ephemeral = true}},
{"Brave.Core.IsDefault", {}},
{"Brave.Core.NumberOfExtensions", {}},
{"Brave.Core.PagesReloaded", {}},
{"Brave.Core.TabCount", {}},
{"Brave.Core.WeeklyUsage", {}},
{"Brave.Core.WeeklyUsage.Nebula", MetricConfig{.nebula = true}},
{"Brave.Core.WindowCount.2", {}},
{"Brave.DNS.AutoSecureRequests.2", MetricConfig{.ephemeral = true}},
{"Brave.DNS.AutoSecureRequests.Cloudflare.2", MetricConfig{.ephemeral = true}},
{"Brave.DNS.AutoSecureRequests.Quad9.2", MetricConfig{.ephemeral = true}},
{"Brave.DNS.AutoSecureRequests.Wikimedia.2", MetricConfig{.ephemeral = true}},
{"Brave.DNS.SecureSetting", {}},
{"Brave.Extensions.AdBlock", {}},
{"Brave.IOS.IsLikelyDefault", {}},
"Brave.Importer.ImporterSource.2",
"Brave.NTP.CustomizeUsageStatus.2",
"Brave.NTP.NewTabsCreated.3",
"Brave.NTP.SponsoredMediaType",
"Brave.Omnibox.SearchCount.3",
{"Brave.Importer.ImporterSource.2", {}},
{"Brave.NTP.CustomizeUsageStatus.2", {}},
{"Brave.NTP.NewTabsCreated.3", {}},
{"Brave.NTP.SponsoredMediaType", {}},
{"Brave.Omnibox.SearchCount.3", {}},
// P2A
// Ad Impressions
"Brave.P2A.ad_notification.impressions",
"Brave.P2A.ad_notification.impressions_per_segment.architecture",
"Brave.P2A.ad_notification.impressions_per_segment.artsentertainment",
"Brave.P2A.ad_notification.impressions_per_segment.automotive",
"Brave.P2A.ad_notification.impressions_per_segment.business",
"Brave.P2A.ad_notification.impressions_per_segment.careers",
"Brave.P2A.ad_notification.impressions_per_segment.cellphones",
"Brave.P2A.ad_notification.impressions_per_segment.crypto",
"Brave.P2A.ad_notification.impressions_per_segment.education",
"Brave.P2A.ad_notification.impressions_per_segment.familyparenting",
"Brave.P2A.ad_notification.impressions_per_segment.fashion",
"Brave.P2A.ad_notification.impressions_per_segment.folklore",
"Brave.P2A.ad_notification.impressions_per_segment.fooddrink",
"Brave.P2A.ad_notification.impressions_per_segment.gaming",
"Brave.P2A.ad_notification.impressions_per_segment.healthfitness",
"Brave.P2A.ad_notification.impressions_per_segment.history",
"Brave.P2A.ad_notification.impressions_per_segment.hobbiesinterests",
"Brave.P2A.ad_notification.impressions_per_segment.home",
"Brave.P2A.ad_notification.impressions_per_segment.law",
"Brave.P2A.ad_notification.impressions_per_segment.military",
"Brave.P2A.ad_notification.impressions_per_segment.other",
"Brave.P2A.ad_notification.impressions_per_segment.personalfinance",
"Brave.P2A.ad_notification.impressions_per_segment.pets",
"Brave.P2A.ad_notification.impressions_per_segment.realestate",
"Brave.P2A.ad_notification.impressions_per_segment.science",
"Brave.P2A.ad_notification.impressions_per_segment.sports",
"Brave.P2A.ad_notification.impressions_per_segment.technologycomputing",
"Brave.P2A.ad_notification.impressions_per_segment.travel",
"Brave.P2A.ad_notification.impressions_per_segment.untargeted",
"Brave.P2A.ad_notification.impressions_per_segment.weather",
// Ad Opportunities
"Brave.P2A.ad_notification.opportunities",
"Brave.P2A.ad_notification.opportunities_per_segment.architecture",
"Brave.P2A.ad_notification.opportunities_per_segment.artsentertainment",
"Brave.P2A.ad_notification.opportunities_per_segment.automotive",
"Brave.P2A.ad_notification.opportunities_per_segment.business",
"Brave.P2A.ad_notification.opportunities_per_segment.careers",
"Brave.P2A.ad_notification.opportunities_per_segment.cellphones",
"Brave.P2A.ad_notification.opportunities_per_segment.crypto",
"Brave.P2A.ad_notification.opportunities_per_segment.education",
"Brave.P2A.ad_notification.opportunities_per_segment.familyparenting",
"Brave.P2A.ad_notification.opportunities_per_segment.fashion",
"Brave.P2A.ad_notification.opportunities_per_segment.folklore",
"Brave.P2A.ad_notification.opportunities_per_segment.fooddrink",
"Brave.P2A.ad_notification.opportunities_per_segment.gaming",
"Brave.P2A.ad_notification.opportunities_per_segment.healthfitness",
"Brave.P2A.ad_notification.opportunities_per_segment.history",
"Brave.P2A.ad_notification.opportunities_per_segment.hobbiesinterests",
"Brave.P2A.ad_notification.opportunities_per_segment.home",
"Brave.P2A.ad_notification.opportunities_per_segment.law",
"Brave.P2A.ad_notification.opportunities_per_segment.military",
"Brave.P2A.ad_notification.opportunities_per_segment.other",
"Brave.P2A.ad_notification.opportunities_per_segment.personalfinance",
"Brave.P2A.ad_notification.opportunities_per_segment.pets",
"Brave.P2A.ad_notification.opportunities_per_segment.realestate",
"Brave.P2A.ad_notification.opportunities_per_segment.science",
"Brave.P2A.ad_notification.opportunities_per_segment.sports",
"Brave.P2A.ad_notification.opportunities_per_segment.technologycomputing",
"Brave.P2A.ad_notification.opportunities_per_segment.travel",
"Brave.P2A.ad_notification.opportunities_per_segment.untargeted",
"Brave.P2A.ad_notification.opportunities_per_segment.weather",
"Brave.P2A.inline_content_ad.impressions",
"Brave.P2A.inline_content_ad.opportunities",
"Brave.P2A.new_tab_page_ad.impressions",
"Brave.P2A.new_tab_page_ad.opportunities",
"Brave.P3A.SentAnswersCount",
"Brave.Playlist.FirstTimeOffset",
"Brave.Playlist.NewUserReturning",
"Brave.Playlist.UsageDaysInWeek",
"Brave.Rewards.AdTypesEnabled.2",
"Brave.Rewards.AutoContributionsState.3",
"Brave.Rewards.DesktopPanelCount",
"Brave.Rewards.EnabledSource",
"Brave.Rewards.MobileConversion",
"Brave.Rewards.MobilePanelCount",
"Brave.Rewards.SearchResultAdsOptin",
"Brave.Rewards.TipsState.2",
"Brave.Rewards.ToolbarButtonTrigger",
"Brave.Rewards.WalletBalance.3",
"Brave.Rewards.WalletState",
"Brave.Search.GoogleWidgetUsage",
"Brave.Search.Promo.BannerB",
"Brave.Search.Promo.BannerC",
"Brave.Search.Promo.BannerD",
"Brave.Search.Promo.Button",
"Brave.Search.Promo.DDGBannerA",
"Brave.Search.Promo.DDGBannerB",
"Brave.Search.Promo.DDGBannerC",
"Brave.Search.Promo.DDGBannerD",
"Brave.Search.Promo.NewTabPage",
"Brave.Search.QueriesBeforeChurn",
"Brave.Search.SwitchEngine",
"Brave.Search.WebDiscoveryAndAds",
"Brave.Search.WebDiscoveryEnabled",
"Brave.Search.WidgetDefault",
"Brave.Search.WidgetUsage",
"Brave.Shields.AdBlockSetting",
"Brave.Shields.CookieListEnabled",
"Brave.Shields.DomainAdsSettingsAboveGlobal",
"Brave.Shields.DomainAdsSettingsBelowGlobal",
"Brave.Shields.FingerprintBlockSetting",
"Brave.Shields.UsageStatus",
"Brave.Sidebar.Enabled",
"Brave.Sidebar.SettingChange.SidebarEnabledA",
"Brave.Sync.JoinType",
"Brave.Sync.Status.2",
"Brave.Today.ClickCardDepth",
"Brave.Today.LastUsageTime",
"Brave.Today.NewUserReturning",
"Brave.Today.NonRewardsAdViews",
"Brave.Today.RewardsAdViews",
"Brave.Today.SidebarFilterUsages",
"Brave.Today.WeeklySessionCount",
"Brave.Today.WeeklyTotalCardClicks",
"Brave.Today.WeeklyTotalCardViews",
"Brave.VPN.HideWidget",
"Brave.VPN.LastUsageTime",
"Brave.VPN.NewUserReturning",
"Brave.VPN.WidgetUsage",
"Brave.VerticalTabs.GroupTabs",
"Brave.VerticalTabs.OpenTabs",
"Brave.VerticalTabs.PinnedTabs",
"Brave.Wallet.ActiveBtcAccounts",
"Brave.Wallet.ActiveEthAccounts",
"Brave.Wallet.ActiveSolAccounts",
"Brave.Wallet.ActiveZecAccounts",
"Brave.Wallet.BtcTransactionSent",
"Brave.Wallet.EthTransactionSent",
"Brave.Wallet.NFTCount",
"Brave.Wallet.NewUserBalance",
"Brave.Wallet.NewUserReturning",
"Brave.Wallet.OnboardingConversion.3",
"Brave.Wallet.SolTransactionSent",
"Brave.Wallet.ZecTransactionSent",
"Brave.WebTorrent.UsageWeekly",
"Brave.Welcome.InteractionStatus.2",
{"Brave.P2A.ad_notification.impressions", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.architecture", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.artsentertainment", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.automotive", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.business", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.careers", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.cellphones", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.crypto", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.education", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.familyparenting", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.fashion", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.folklore", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.fooddrink", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.gaming", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.healthfitness", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.history", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.hobbiesinterests", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.home", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.law", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.military", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.other", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.personalfinance", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.pets", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.realestate", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.science", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.sports", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.technologycomputing", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.travel", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.untargeted", {}},
{"Brave.P2A.ad_notification.impressions_per_segment.weather", {}},
// Ad Opportunities
{"Brave.P2A.ad_notification.opportunities", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.architecture", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.artsentertainment", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.automotive", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.business", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.careers", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.cellphones", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.crypto", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.education", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.familyparenting", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.fashion", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.folklore", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.fooddrink", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.gaming", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.healthfitness", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.history", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.hobbiesinterests", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.home", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.law", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.military", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.other", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.personalfinance", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.pets", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.realestate", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.science", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.sports", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.technologycomputing", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.travel", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.untargeted", {}},
{"Brave.P2A.ad_notification.opportunities_per_segment.weather", {}},
{"Brave.P2A.inline_content_ad.impressions", {}},
{"Brave.P2A.inline_content_ad.opportunities", {}},
{"Brave.P2A.new_tab_page_ad.impressions", {}},
{"Brave.P2A.new_tab_page_ad.opportunities", {}},
{"Brave.P3A.SentAnswersCount", {}},
{"Brave.Playlist.FirstTimeOffset", MetricConfig{.ephemeral = true}},
{"Brave.Playlist.NewUserReturning", {}},
{"Brave.Playlist.UsageDaysInWeek", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.AdTypesEnabled.2", {}},
{"Brave.Rewards.AutoContributionsState.3", {}},
{"Brave.Rewards.DesktopPanelCount", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.EnabledSource", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.MobileConversion", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.MobilePanelCount", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.SearchResultAdsOptin", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.TipsState.2", {}},
{"Brave.Rewards.ToolbarButtonTrigger", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.WalletBalance.3", {}},
{"Brave.Rewards.WalletState", {}},
{"Brave.Search.GoogleWidgetUsage", MetricConfig{.ephemeral = true}},
{"Brave.Search.Promo.BannerB", {}},
{"Brave.Search.Promo.BannerC", {}},
{"Brave.Search.Promo.BannerD", {}},
{"Brave.Search.Promo.Button", {}},
{"Brave.Search.Promo.DDGBannerA", {}},
{"Brave.Search.Promo.DDGBannerB", {}},
{"Brave.Search.Promo.DDGBannerC", {}},
{"Brave.Search.Promo.DDGBannerD", {}},
{"Brave.Search.Promo.NewTabPage", {}},
{"Brave.Search.QueriesBeforeChurn", MetricConfig{.ephemeral = true}},
{"Brave.Search.SwitchEngine", {}},
{"Brave.Search.WebDiscoveryAndAds", {}},
{"Brave.Search.WebDiscoveryEnabled", {}},
{"Brave.Search.WidgetDefault", {}},
{"Brave.Search.WidgetUsage", MetricConfig{.ephemeral = true}},
{"Brave.Shields.AdBlockSetting", {}},
{"Brave.Shields.CookieListEnabled", {}},
{"Brave.Shields.DomainAdsSettingsAboveGlobal", {}},
{"Brave.Shields.DomainAdsSettingsBelowGlobal", {}},
{"Brave.Shields.FingerprintBlockSetting", {}},
{"Brave.Shields.UsageStatus", {}},
{"Brave.Sidebar.Enabled", {}},
{"Brave.Sidebar.SettingChange.SidebarEnabledA", {}},
{"Brave.Sync.JoinType", MetricConfig{.ephemeral = true}},
{"Brave.Sync.Status.2", {}},
{"Brave.Today.ClickCardDepth", MetricConfig{.ephemeral = true}},
{"Brave.Today.LastUsageTime", {}},
{"Brave.Today.NewUserReturning", {}},
{"Brave.Today.NonRewardsAdViews", {}},
{"Brave.Today.RewardsAdViews", {}},
{"Brave.Today.SidebarFilterUsages", MetricConfig{.ephemeral = true}},
{"Brave.Today.WeeklySessionCount", {}},
{"Brave.Today.WeeklyTotalCardClicks", MetricConfig{.ephemeral = true}},
{"Brave.Today.WeeklyTotalCardViews", {}},
{"Brave.VPN.HideWidget", MetricConfig{.ephemeral = true}},
{"Brave.VPN.LastUsageTime", {}},
{"Brave.VPN.NewUserReturning", {}},
{"Brave.VPN.WidgetUsage", MetricConfig{.ephemeral = true}},
{"Brave.VerticalTabs.GroupTabs", MetricConfig{.ephemeral = true}},
{"Brave.VerticalTabs.OpenTabs", MetricConfig{.ephemeral = true}},
{"Brave.VerticalTabs.PinnedTabs", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.ActiveBtcAccounts", {}},
{"Brave.Wallet.ActiveEthAccounts", {}},
{"Brave.Wallet.ActiveSolAccounts", {}},
{"Brave.Wallet.ActiveZecAccounts", {}},
{"Brave.Wallet.BtcTransactionSent", {}},
{"Brave.Wallet.EthTransactionSent", {}},
{"Brave.Wallet.NFTCount", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.NewUserBalance", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.NewUserReturning", {}},
{"Brave.Wallet.OnboardingConversion.3", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.SolTransactionSent", {}},
{"Brave.Wallet.ZecTransactionSent", {}},
{"Brave.WebTorrent.UsageWeekly", MetricConfig{.ephemeral = true}},
{"Brave.Welcome.InteractionStatus.2", {}},
});
inline constexpr auto kCollectedSlowHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.AIChat.ContextMenu.LastUsageTime",
"Brave.AIChat.LastUsageTime",
"Brave.AIChat.UsageMonthly",
"Brave.Core.PrimaryLang",
"Brave.Core.ProfileCount",
"Brave.Core.UsageMonthly",
"Brave.P3A.TestSlowMetric",
"Brave.Playlist.LastUsageTime",
"Brave.Rewards.PageViewCount",
"Brave.Rewards.RecurringTip",
"Brave.Rewards.TipsSent.2",
"Brave.Search.SearchSuggest",
"Brave.Shields.ForgetFirstParty",
"Brave.Sync.EnabledTypes",
"Brave.Sync.SyncedObjectsCount.2",
"Brave.Today.ChannelCount.2",
"Brave.Today.DirectFeedsTotal.3",
"Brave.Today.PublisherCount.2",
"Brave.Today.UsageMonthly",
"Brave.Wallet.UsageMonthly",
base::MakeFixedFlatMap<std::string_view, std::optional<MetricConfig>>({
{"Brave.AIChat.ContextMenu.LastUsageTime", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.LastUsageTime", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.UsageMonthly", MetricConfig{.ephemeral = true}},
{"Brave.Core.PrimaryLang", MetricConfig{.constellation_only = true}},
{"Brave.Core.ProfileCount", {}},
{"Brave.Core.UsageMonthly", {}},
{"Brave.P3A.TestSlowMetric", {}},
{"Brave.Playlist.LastUsageTime", {}},
{"Brave.Rewards.PageViewCount", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.RecurringTip", MetricConfig{.ephemeral = true}},
{"Brave.Rewards.TipsSent.2", MetricConfig{.ephemeral = true}},
{"Brave.Search.SearchSuggest", {}},
{"Brave.Shields.ForgetFirstParty", {}},
{"Brave.Sync.EnabledTypes", {}},
{"Brave.Sync.SyncedObjectsCount.2", {}},
{"Brave.Today.ChannelCount.2", MetricConfig{.ephemeral = true}},
{"Brave.Today.DirectFeedsTotal.3", MetricConfig{.ephemeral = true}},
{"Brave.Today.PublisherCount.2", MetricConfig{.ephemeral = true}},
{"Brave.Today.UsageMonthly", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.UsageMonthly", MetricConfig{.ephemeral = true}},
});
inline constexpr auto kCollectedExpressHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.AIChat.UsageDaily.2",
"Brave.AIChat.UsageDaily.SidebarEnabledA",
"Brave.Core.UsageDaily",
"Brave.DayZero.A.InstallTime",
"Brave.DayZero.B.InstallTime",
"Brave.Rewards.EnabledInstallationTime",
"Brave.Search.BraveDaily",
"Brave.Search.DefaultEngine.4",
"Brave.Today.IsEnabled",
"Brave.Today.UsageDaily",
"Brave.Uptime.BrowserOpenTime.2",
"Brave.Wallet.UsageDaily",
"creativeInstanceId.total.count",
base::MakeFixedFlatMap<std::string_view, std::optional<MetricConfig>>({
{"Brave.AIChat.UsageDaily.2", MetricConfig{.ephemeral = true}},
{"Brave.AIChat.UsageDaily.SidebarEnabledA", MetricConfig{.ephemeral = true}},
{"Brave.Core.UsageDaily", {}},
{"Brave.DayZero.A.InstallTime", MetricConfig{
.ephemeral = true,
.constellation_only = true,
.append_attributes = MetricAttributesToAppend{MetricAttribute::kRef}
}},
{"Brave.DayZero.B.InstallTime", MetricConfig{
.ephemeral = true,
.constellation_only = true,
.append_attributes = MetricAttributesToAppend{MetricAttribute::kRef}
}},
{"Brave.Rewards.EnabledInstallationTime", MetricConfig{.ephemeral = true}},
{"Brave.Search.BraveDaily", MetricConfig{.ephemeral = true}},
{"Brave.Search.DefaultEngine.4", {}},
{"Brave.Today.IsEnabled", MetricConfig{.ephemeral = true}},
{"Brave.Today.UsageDaily", MetricConfig{.ephemeral = true}},
{"Brave.Uptime.BrowserOpenTime.2", MetricConfig{.ephemeral = true}},
{"Brave.Wallet.UsageDaily", MetricConfig{.ephemeral = true}},
{"creativeInstanceId.total.count", {}},
});
// List of metrics that should only be sent once per latest histogram update.
// Once the metric value has been sent, the value will be removed from the log store.
inline constexpr auto kEphemeralHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.AIChat.AcquisitionSource",
"Brave.AIChat.AvgPromptCount",
"Brave.AIChat.ChatCount",
"Brave.AIChat.ContextMenu.FreeUsages",
"Brave.AIChat.ContextMenu.LastUsageTime",
"Brave.AIChat.ContextMenu.MostUsedAction",
"Brave.AIChat.ContextMenu.PremiumUsages",
"Brave.AIChat.LastUsageTime",
"Brave.AIChat.MostUsedEntryPoint",
"Brave.AIChat.OmniboxOpens",
"Brave.AIChat.OmniboxWeekCompare",
"Brave.AIChat.UsageDaily.2",
"Brave.AIChat.UsageDaily.SidebarEnabledA",
"Brave.AIChat.UsageMonthly",
"Brave.AIChat.UsageWeekly",
"Brave.AIChat.UsageWeekly.SidebarEnabledA",
"Brave.Ads.ClearData",
"Brave.Core.FailedHTTPSUpgrades.2",
"Brave.Core.FirstPageLoadTime",
"Brave.DNS.AutoSecureRequests.2",
"Brave.DNS.AutoSecureRequests.Cloudflare.2",
"Brave.DNS.AutoSecureRequests.Quad9.2",
"Brave.DNS.AutoSecureRequests.Wikimedia.2",
"Brave.DayZero.A.InstallTime",
"Brave.DayZero.B.InstallTime",
"Brave.Playlist.FirstTimeOffset",
"Brave.Playlist.UsageDaysInWeek",
"Brave.Rewards.DesktopPanelCount",
"Brave.Rewards.EnabledInstallationTime",
"Brave.Rewards.EnabledSource",
"Brave.Rewards.MobileConversion",
"Brave.Rewards.MobilePanelCount",
"Brave.Rewards.PageViewCount",
"Brave.Rewards.RecurringTip",
"Brave.Rewards.SearchResultAdsOptin",
"Brave.Rewards.TipsSent.2",
"Brave.Rewards.ToolbarButtonTrigger",
"Brave.Search.BraveDaily",
"Brave.Search.GoogleWidgetUsage",
"Brave.Search.QueriesBeforeChurn",
"Brave.Search.WidgetUsage",
"Brave.Sync.JoinType",
"Brave.Today.ChannelCount.2",
"Brave.Today.ClickCardDepth",
"Brave.Today.DirectFeedsTotal.3",
"Brave.Today.IsEnabled",
"Brave.Today.PublisherCount.2",
"Brave.Today.SidebarFilterUsages",
"Brave.Today.UsageDaily",
"Brave.Today.UsageMonthly",
"Brave.Today.WeeklyTotalCardClicks",
"Brave.Uptime.BrowserOpenTime.2",
"Brave.VPN.HideWidget",
"Brave.VPN.WidgetUsage",
"Brave.VerticalTabs.GroupTabs",
"Brave.VerticalTabs.OpenTabs",
"Brave.VerticalTabs.PinnedTabs",
"Brave.Wallet.NFTCount",
"Brave.Wallet.NewUserBalance",
"Brave.Wallet.OnboardingConversion.3",
"Brave.Wallet.UsageDaily",
"Brave.Wallet.UsageMonthly",
"Brave.WebTorrent.UsageWeekly",
});
// List of metrics that should only be via STAR/Constellation.
// TODO(djandries): remove this once JSON deprecation is complete
inline constexpr auto kConstellationOnlyHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.Core.PrimaryLang",
"Brave.DayZero.A.InstallTime",
"Brave.DayZero.B.InstallTime",
});
// List of metrics which will include the stored refcode when transmitted
// via the STAR/Constellation protocol.
inline constexpr auto kHistogramsWithRefcodeIncluded =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.DayZero.A.InstallTime",
"Brave.DayZero.B.InstallTime",
});
// List of metrics that should be protected by Nebula.
//
// We intend to apply Nebula to all questions by default,
// subject to verification that it behaves as expected.
// This list tests a small number of questions to confirm
// this, and should be removed or converted to an exception
// list once we're satisfied with the implementation.
inline constexpr auto kNebulaOnlyHistograms =
base::MakeFixedFlatSet<std::string_view>(base::sorted_unique,{
"Brave.AIChat.ChatCount.Nebula",
"Brave.Core.WeeklyUsage.Nebula",
});
// clang-format on
} // namespace p3a
// clang-format on
#endif // BRAVE_COMPONENTS_P3A_METRIC_NAMES_H_
+4 -4
View File
@@ -35,12 +35,12 @@ TEST(P3AMetrics, Enumerable) {
// Check that we can loop through the set members.
DLOG(INFO) << "Set of collected metrics has " << size << " members:";
for (auto item : kCollectedTypicalHistograms) {
DLOG(INFO) << " " << item;
DLOG(INFO) << " " << item.first;
// Each item should be a set member.
EXPECT_TRUE(kCollectedTypicalHistograms.contains(item));
EXPECT_TRUE(kCollectedTypicalHistograms.contains(item.first));
// Each item should be different from the previous one.
EXPECT_NE(item, last);
last = std::string(item);
EXPECT_NE(item.first, last);
last = std::string(item.first);
// Count the number of items.
count++;
}
+132 -49
View File
@@ -11,7 +11,6 @@
#include <vector>
#include "base/containers/fixed_flat_set.h"
#include "base/containers/flat_set.h"
#include "base/i18n/timezone.h"
#include "base/logging.h"
#include "base/strings/strcat.h"
@@ -20,7 +19,8 @@
#include "base/strings/string_util.h"
#include "brave/components/brave_stats/browser/brave_stats_updater_util.h"
#include "brave/components/l10n/common/locale_util.h"
#include "brave/components/l10n/common/prefs.h"
#include "brave/components/p3a/metric_config.h"
#include "brave/components/p3a/region.h"
#include "brave/components/p3a/uploader.h"
#include "brave/components/version_info/version_info.h"
#include "components/prefs/pref_service.h"
@@ -37,6 +37,7 @@ constexpr char kMetricNameAttributeName[] = "metric_name";
constexpr char kMetricValueAttributeName[] = "metric_value";
constexpr char kMetricNameAndValueAttributeName[] = "metric_name_and_value";
constexpr char kPlatformAttributeName[] = "platform";
constexpr char kGeneralPlatformAttributeName[] = "general_platform";
constexpr char kChannelAttributeName[] = "channel";
constexpr char kYosAttributeName[] = "yos";
constexpr char kWosAttributeName[] = "wos";
@@ -45,6 +46,8 @@ constexpr char kWoiAttributeName[] = "woi";
constexpr char kYoiAttributeName[] = "yoi";
constexpr char kCountryCodeAttributeName[] = "country_code";
constexpr char kVersionAttributeName[] = "version";
constexpr char kRegionAttributeName[] = "region";
constexpr char kSubregionAttributeName[] = "subregion";
constexpr char kCadenceAttributeName[] = "cadence";
constexpr char kRefAttributeName[] = "ref";
@@ -64,6 +67,92 @@ constexpr auto kNotableCountries = base::MakeFixedFlatSet<std::string_view>(
{"US", "FR", "PH", "GB", "IN", "DE", "BR", "CA", "IT", "ES",
"NL", "MX", "AU", "RU", "JP", "PL", "ID", "KR", "AR", "AT"});
std::vector<std::array<std::string, 2>> PopulateConstellationAttributes(
const std::string_view metric_name,
const uint64_t metric_value,
const MessageMetainfo& meta,
const std::optional<MetricConfig>& metric_config,
const std::vector<MetricAttribute>& attributes_to_load,
bool is_creative) {
base::Time::Exploded exploded;
meta.date_of_install().LocalExplode(&exploded);
DCHECK_GE(exploded.year, 999);
std::vector<std::array<std::string, 2>> attributes;
if (metric_config && metric_config->nebula) {
attributes = {
{kMetricNameAndValueAttributeName,
base::JoinString({metric_name, base::NumberToString(metric_value)},
kP3AMessageNebulaNameValueSeparator)}};
} else {
attributes = {{kMetricNameAttributeName, std::string(metric_name)}};
}
std::string country_code;
for (const auto& attribute : attributes_to_load) {
switch (attribute) {
case MetricAttribute::kAnswerIndex:
if (metric_config && metric_config->nebula) {
continue;
}
attributes.push_back(
{kMetricValueAttributeName, base::NumberToString(metric_value)});
break;
case MetricAttribute::kVersion:
if (is_creative) {
continue;
}
attributes.push_back({kVersionAttributeName, meta.version()});
break;
case MetricAttribute::kYoi:
if (is_creative) {
continue;
}
attributes.push_back(
{kYoiAttributeName, base::NumberToString(exploded.year)});
break;
case MetricAttribute::kChannel:
attributes.push_back({kChannelAttributeName, meta.channel()});
break;
case MetricAttribute::kPlatform:
attributes.push_back({kPlatformAttributeName, meta.platform()});
break;
case MetricAttribute::kCountryCode:
if (is_creative) {
country_code = meta.country_code_from_locale_raw();
} else {
country_code = meta.GetCountryCodeForNormalMetrics(
metric_config && metric_config->disable_country_strip);
}
attributes.push_back({kCountryCodeAttributeName, country_code});
break;
case MetricAttribute::kWoi:
if (is_creative) {
continue;
}
attributes.push_back(
{kWoiAttributeName, base::NumberToString(meta.woi())});
break;
case MetricAttribute::kGeneralPlatform:
attributes.push_back(
{kGeneralPlatformAttributeName, meta.general_platform()});
break;
case MetricAttribute::kRegion:
attributes.push_back({kRegionAttributeName,
std::string(meta.region_identifiers().region)});
break;
case MetricAttribute::kSubregion:
attributes.push_back(
{kSubregionAttributeName,
std::string(meta.region_identifiers().sub_region)});
break;
case MetricAttribute::kRef:
attributes.push_back({kRefAttributeName, meta.ref()});
break;
}
}
return attributes;
}
} // namespace
MessageMetainfo::MessageMetainfo() = default;
@@ -112,7 +201,8 @@ base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
result.Set(kYoiAttributeName, install_exploded.year);
// Fill meta.
result.Set(kCountryCodeAttributeName, meta.GetCountryCodeForNormalMetrics());
result.Set(kCountryCodeAttributeName,
meta.GetCountryCodeForNormalMetrics(false));
result.Set(kVersionAttributeName, meta.version());
result.Set(kWoiAttributeName, meta.woi());
@@ -140,53 +230,34 @@ base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
return result;
}
std::string GenerateP3AConstellationMessage(std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type,
bool include_refcode,
bool is_nebula) {
base::Time::Exploded exploded;
meta.date_of_install().LocalExplode(&exploded);
DCHECK_GE(exploded.year, 999);
std::vector<std::array<std::string, 2>> attributes;
std::string metric_name_str = std::string(metric_name);
std::string metric_value_str = base::NumberToString(metric_value);
if (!is_nebula) {
attributes = {{{kMetricNameAttributeName, metric_name_str},
{kMetricValueAttributeName, metric_value_str}}};
std::string GenerateP3AConstellationMessage(
std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type,
const std::optional<MetricConfig>& metric_config) {
std::vector<MetricAttribute> attributes_to_load;
if (metric_config && metric_config->attributes) {
for (const auto& attr : *metric_config->attributes) {
if (attr.has_value()) {
attributes_to_load.push_back(attr.value());
}
}
} else {
attributes = {{kMetricNameAndValueAttributeName,
base::JoinString({metric_name_str, metric_value_str},
kP3AMessageNebulaNameValueSeparator)}};
attributes_to_load.assign(std::begin(kDefaultMetricAttributes),
std::end(kDefaultMetricAttributes));
if (metric_config && !metric_config->append_attributes.empty()) {
for (const auto& attr : metric_config->append_attributes) {
if (attr.has_value()) {
attributes_to_load.push_back(attr.value());
}
}
}
}
bool is_creative = upload_type == kP3ACreativeUploadType;
if (!is_creative) {
attributes.push_back({kVersionAttributeName, meta.version()});
attributes.push_back(
{kYoiAttributeName, base::NumberToString(exploded.year)});
}
attributes.push_back({kChannelAttributeName, meta.channel()});
attributes.push_back({kPlatformAttributeName, meta.platform()});
if (is_creative) {
attributes.push_back(
{kCountryCodeAttributeName, meta.country_code_from_locale_raw()});
} else {
attributes.push_back(
{kCountryCodeAttributeName, meta.GetCountryCodeForNormalMetrics()});
attributes.push_back({kWoiAttributeName, base::NumberToString(meta.woi())});
}
if (include_refcode) {
attributes.push_back({kRefAttributeName, meta.ref()});
}
auto attributes = PopulateConstellationAttributes(
metric_name, metric_value, meta, metric_config, attributes_to_load,
upload_type == kP3ACreativeUploadType);
std::vector<std::string> serialized_attributes(attributes.size());
@@ -205,6 +276,7 @@ void MessageMetainfo::Init(PrefService* local_state,
std::string week_of_install) {
local_state_ = local_state;
platform_ = brave_stats::GetPlatformIdentifier();
general_platform_ = brave_stats::GetGeneralPlatformIdentifier();
channel_ = brave_channel;
InitVersion();
InitRef();
@@ -216,11 +288,15 @@ void MessageMetainfo::Init(PrefService* local_state,
}
woi_ = brave_stats::GetIsoWeekNumber(date_of_install_);
country_code_from_timezone_ =
country_code_from_timezone_raw_ =
base::ToUpperASCII(base::CountryCodeForCurrentTimezone());
country_code_from_locale_raw_ = brave_l10n::GetDefaultISOCountryCodeString();
country_code_from_timezone_ = country_code_from_timezone_raw_;
country_code_from_locale_ = country_code_from_locale_raw_;
region_identifiers_ =
GetRegionIdentifiers(GetCountryCodeForNormalMetrics(true));
MaybeStripCountry();
Update();
@@ -285,10 +361,17 @@ void MessageMetainfo::MaybeStripCountry() {
}
}
const std::string& MessageMetainfo::GetCountryCodeForNormalMetrics() const {
const std::string& MessageMetainfo::GetCountryCodeForNormalMetrics(
bool raw) const {
#if BUILDFLAG(IS_IOS)
if (raw) {
return country_code_from_locale_raw_;
}
return country_code_from_locale_;
#else
if (raw) {
return country_code_from_timezone_raw_;
}
return country_code_from_timezone_;
#endif // BUILDFLAG(IS_IOS)
}
+16 -7
View File
@@ -12,7 +12,9 @@
#include "base/time/time.h"
#include "base/values.h"
#include "brave/components/p3a/metric_config.h"
#include "brave/components/p3a/metric_log_type.h"
#include "brave/components/p3a/region.h"
class PrefService;
@@ -33,15 +35,19 @@ class MessageMetainfo {
void Update();
const std::string& GetCountryCodeForNormalMetrics() const;
const std::string& GetCountryCodeForNormalMetrics(bool raw) const;
const std::string& platform() const { return platform_; }
const std::string& general_platform() const { return general_platform_; }
const std::string& channel() const { return channel_; }
const std::string& version() const { return version_; }
const std::string& country_code_from_locale_raw() const {
return country_code_from_locale_raw_;
}
const std::string& ref() const { return ref_; }
const RegionIdentifiers& region_identifiers() const {
return region_identifiers_;
}
base::Time date_of_install() const { return date_of_install_; }
base::Time date_of_survey() const { return date_of_survey_; }
int woi() const { return woi_; }
@@ -59,6 +65,7 @@ class MessageMetainfo {
void MaybeStripCountry();
std::string platform_;
std::string general_platform_;
std::string version_;
std::string channel_;
base::Time date_of_install_;
@@ -66,8 +73,10 @@ class MessageMetainfo {
int woi_; // Week of install. Remove this occasionally and extract from
// above.
std::string country_code_from_timezone_;
std::string country_code_from_timezone_raw_;
std::string country_code_from_locale_;
std::string country_code_from_locale_raw_;
RegionIdentifiers region_identifiers_;
// May contain 'none', a 'BRV'-prefixed refcode, or 'other'.
std::string ref_;
@@ -80,12 +89,12 @@ base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
const MessageMetainfo& meta,
const std::string& upload_type);
std::string GenerateP3AConstellationMessage(std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type,
bool include_refcode,
bool is_nebula);
std::string GenerateP3AConstellationMessage(
std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type,
const std::optional<MetricConfig>& metric_config);
} // namespace p3a
+5 -6
View File
@@ -109,15 +109,13 @@ void P3AService::InitCallback(std::string_view histogram_name) {
}
void P3AService::InitCallbacks() {
for (const std::string_view histogram_name :
p3a::kCollectedTypicalHistograms) {
for (const auto& [histogram_name, _] : p3a::kCollectedTypicalHistograms) {
InitCallback(histogram_name);
}
for (const std::string_view histogram_name :
p3a::kCollectedExpressHistograms) {
for (const auto& [histogram_name, _] : p3a::kCollectedExpressHistograms) {
InitCallback(histogram_name);
}
for (const std::string_view histogram_name : p3a::kCollectedSlowHistograms) {
for (const auto& [histogram_name, _] : p3a::kCollectedSlowHistograms) {
InitCallback(histogram_name);
}
for (const auto& [histogram_name, log_type] : dynamic_metric_log_types_) {
@@ -315,7 +313,8 @@ void P3AService::HandleHistogramChange(
only_update_for_constellation);
return;
}
if (kConstellationOnlyHistograms.contains(histogram_name)) {
const auto* metric_config = message_manager_->GetMetricConfig(histogram_name);
if (metric_config && *metric_config && (*metric_config)->constellation_only) {
only_update_for_constellation = true;
}
message_manager_->UpdateMetricValue(std::string(histogram_name), bucket,
+5 -6
View File
@@ -104,16 +104,15 @@ class P3AServiceTest : public testing::Test {
std::vector<std::string> result;
size_t p3a_i = 0;
size_t p2a_i = 0;
for (const std::string_view histogram_name :
p3a::kCollectedTypicalHistograms) {
if (histogram_name.rfind(kP2APrefix, 0) == 0) {
for (const auto& histogram_pair : p3a::kCollectedTypicalHistograms) {
if (histogram_pair.first.rfind(kP2APrefix, 0) == 0) {
if (p2a_i < p2a_count) {
result.push_back(std::string(histogram_name));
result.push_back(std::string(histogram_pair.first));
p2a_i++;
}
} else if (p3a_i < p3a_count &&
histogram_name.starts_with("Brave.Core")) {
result.push_back(std::string(histogram_name));
histogram_pair.first.starts_with("Brave.Core")) {
result.push_back(std::string(histogram_pair.first));
p3a_i++;
}
+350
View File
@@ -0,0 +1,350 @@
/* Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/. */
#include "brave/components/p3a/region.h"
#include <utility>
#include "base/containers/fixed_flat_map.h"
namespace p3a {
namespace {
constexpr char kOtherIdentifier[] = "other";
enum class Region {
kAsia,
kEurope,
kAfrica,
kOceania,
kAmericas,
};
enum class Subregion {
kSouthernAsia,
kNorthernEurope,
kSouthernEurope,
kNorthernAfrica,
kSubSaharanAfrica,
kLatinAmericaAndTheCaribbean,
kWesternAsia,
kWesternEurope,
kEasternEurope,
kNorthernAmerica,
kSoutheasternAsia,
kEasternAsia,
kOceania,
kCentralAsia,
};
inline constexpr auto kCountryRegions =
base::MakeFixedFlatMap<std::string_view, std::pair<Region, Subregion>>({
{"AF", {Region::kAsia, Subregion::kSouthernAsia}},
{"AX", {Region::kEurope, Subregion::kNorthernEurope}},
{"AL", {Region::kEurope, Subregion::kSouthernEurope}},
{"DZ", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"AS", {Region::kOceania, Subregion::kOceania}},
{"AD", {Region::kEurope, Subregion::kSouthernEurope}},
{"AO", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"AI", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"AG", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"AR", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"AM", {Region::kAsia, Subregion::kWesternAsia}},
{"AW", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"AU", {Region::kOceania, Subregion::kOceania}},
{"AT", {Region::kEurope, Subregion::kWesternEurope}},
{"AZ", {Region::kAsia, Subregion::kWesternAsia}},
{"BS", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BH", {Region::kAsia, Subregion::kWesternAsia}},
{"BD", {Region::kAsia, Subregion::kSouthernAsia}},
{"BB", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BY", {Region::kEurope, Subregion::kEasternEurope}},
{"BE", {Region::kEurope, Subregion::kWesternEurope}},
{"BZ", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BJ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"BM", {Region::kAmericas, Subregion::kNorthernAmerica}},
{"BT", {Region::kAsia, Subregion::kSouthernAsia}},
{"BO", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BQ", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BA", {Region::kEurope, Subregion::kSouthernEurope}},
{"BW", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"BV", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"BR", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"IO", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"BN", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"BG", {Region::kEurope, Subregion::kEasternEurope}},
{"BF", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"BI", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CV", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"KH", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"CM", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CA", {Region::kAmericas, Subregion::kNorthernAmerica}},
{"KY", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"CF", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"TD", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CL", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"CN", {Region::kAsia, Subregion::kEasternAsia}},
{"CX", {Region::kOceania, Subregion::kOceania}},
{"CC", {Region::kOceania, Subregion::kOceania}},
{"CO", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"KM", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CG", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CD", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"CK", {Region::kOceania, Subregion::kOceania}},
{"CR", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"CI", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"HR", {Region::kEurope, Subregion::kSouthernEurope}},
{"CU", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"CW", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"CY", {Region::kAsia, Subregion::kWesternAsia}},
{"CZ", {Region::kEurope, Subregion::kEasternEurope}},
{"DK", {Region::kEurope, Subregion::kNorthernEurope}},
{"DJ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"DM", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"DO", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"EC", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"EG", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"SV", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"GQ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"ER", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"EE", {Region::kEurope, Subregion::kNorthernEurope}},
{"SZ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"ET", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"FK", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"FO", {Region::kEurope, Subregion::kNorthernEurope}},
{"FJ", {Region::kOceania, Subregion::kOceania}},
{"FI", {Region::kEurope, Subregion::kNorthernEurope}},
{"FR", {Region::kEurope, Subregion::kWesternEurope}},
{"GF", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"PF", {Region::kOceania, Subregion::kOceania}},
{"TF", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GA", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GM", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GE", {Region::kAsia, Subregion::kWesternAsia}},
{"DE", {Region::kEurope, Subregion::kWesternEurope}},
{"GH", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GI", {Region::kEurope, Subregion::kSouthernEurope}},
{"GR", {Region::kEurope, Subregion::kSouthernEurope}},
{"GL", {Region::kAmericas, Subregion::kNorthernAmerica}},
{"GD", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"GP", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"GU", {Region::kOceania, Subregion::kOceania}},
{"GT", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"GG", {Region::kEurope, Subregion::kNorthernEurope}},
{"GN", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GW", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GY", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"HT", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"HM", {Region::kOceania, Subregion::kOceania}},
{"VA", {Region::kEurope, Subregion::kSouthernEurope}},
{"HN", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"HK", {Region::kAsia, Subregion::kEasternAsia}},
{"HU", {Region::kEurope, Subregion::kEasternEurope}},
{"IS", {Region::kEurope, Subregion::kNorthernEurope}},
{"IN", {Region::kAsia, Subregion::kSouthernAsia}},
{"ID", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"IR", {Region::kAsia, Subregion::kSouthernAsia}},
{"IQ", {Region::kAsia, Subregion::kWesternAsia}},
{"IE", {Region::kEurope, Subregion::kNorthernEurope}},
{"IM", {Region::kEurope, Subregion::kNorthernEurope}},
{"IL", {Region::kAsia, Subregion::kWesternAsia}},
{"IT", {Region::kEurope, Subregion::kSouthernEurope}},
{"JM", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"JP", {Region::kAsia, Subregion::kEasternAsia}},
{"JE", {Region::kEurope, Subregion::kNorthernEurope}},
{"JO", {Region::kAsia, Subregion::kWesternAsia}},
{"KZ", {Region::kAsia, Subregion::kCentralAsia}},
{"KE", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"KI", {Region::kOceania, Subregion::kOceania}},
{"KP", {Region::kAsia, Subregion::kEasternAsia}},
{"KR", {Region::kAsia, Subregion::kEasternAsia}},
{"KW", {Region::kAsia, Subregion::kWesternAsia}},
{"KG", {Region::kAsia, Subregion::kCentralAsia}},
{"LA", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"LV", {Region::kEurope, Subregion::kNorthernEurope}},
{"LB", {Region::kAsia, Subregion::kWesternAsia}},
{"LS", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"LR", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"LY", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"LI", {Region::kEurope, Subregion::kWesternEurope}},
{"LT", {Region::kEurope, Subregion::kNorthernEurope}},
{"LU", {Region::kEurope, Subregion::kWesternEurope}},
{"MO", {Region::kAsia, Subregion::kEasternAsia}},
{"MG", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MW", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MY", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"MV", {Region::kAsia, Subregion::kSouthernAsia}},
{"ML", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MT", {Region::kEurope, Subregion::kSouthernEurope}},
{"MH", {Region::kOceania, Subregion::kOceania}},
{"MQ", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"MR", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MU", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"YT", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MX", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"FM", {Region::kOceania, Subregion::kOceania}},
{"MD", {Region::kEurope, Subregion::kEasternEurope}},
{"MC", {Region::kEurope, Subregion::kWesternEurope}},
{"MN", {Region::kAsia, Subregion::kEasternAsia}},
{"ME", {Region::kEurope, Subregion::kSouthernEurope}},
{"MS", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"MA", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"MZ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"MM", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"NA", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"NR", {Region::kOceania, Subregion::kOceania}},
{"NP", {Region::kAsia, Subregion::kSouthernAsia}},
{"NL", {Region::kEurope, Subregion::kWesternEurope}},
{"NC", {Region::kOceania, Subregion::kOceania}},
{"NZ", {Region::kOceania, Subregion::kOceania}},
{"NI", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"NE", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"NG", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"NU", {Region::kOceania, Subregion::kOceania}},
{"NF", {Region::kOceania, Subregion::kOceania}},
{"MK", {Region::kEurope, Subregion::kSouthernEurope}},
{"MP", {Region::kOceania, Subregion::kOceania}},
{"NO", {Region::kEurope, Subregion::kNorthernEurope}},
{"OM", {Region::kAsia, Subregion::kWesternAsia}},
{"PK", {Region::kAsia, Subregion::kSouthernAsia}},
{"PW", {Region::kOceania, Subregion::kOceania}},
{"PS", {Region::kAsia, Subregion::kWesternAsia}},
{"PA", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"PG", {Region::kOceania, Subregion::kOceania}},
{"PY", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"PE", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"PH", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"PN", {Region::kOceania, Subregion::kOceania}},
{"PL", {Region::kEurope, Subregion::kEasternEurope}},
{"PT", {Region::kEurope, Subregion::kSouthernEurope}},
{"PR", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"QA", {Region::kAsia, Subregion::kWesternAsia}},
{"RE", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"RO", {Region::kEurope, Subregion::kEasternEurope}},
{"RU", {Region::kEurope, Subregion::kEasternEurope}},
{"RW", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"BL", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"SH", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"KN", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"LC", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"MF", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"PM", {Region::kAmericas, Subregion::kNorthernAmerica}},
{"VC", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"WS", {Region::kOceania, Subregion::kOceania}},
{"SM", {Region::kEurope, Subregion::kSouthernEurope}},
{"ST", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"SA", {Region::kAsia, Subregion::kWesternAsia}},
{"SN", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"RS", {Region::kEurope, Subregion::kSouthernEurope}},
{"SC", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"SL", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"SG", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"SX", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"SK", {Region::kEurope, Subregion::kEasternEurope}},
{"SI", {Region::kEurope, Subregion::kSouthernEurope}},
{"SB", {Region::kOceania, Subregion::kOceania}},
{"SO", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"ZA", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"GS", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"SS", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"ES", {Region::kEurope, Subregion::kSouthernEurope}},
{"LK", {Region::kAsia, Subregion::kSouthernAsia}},
{"SD", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"SR", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"SJ", {Region::kEurope, Subregion::kNorthernEurope}},
{"SE", {Region::kEurope, Subregion::kNorthernEurope}},
{"CH", {Region::kEurope, Subregion::kWesternEurope}},
{"SY", {Region::kAsia, Subregion::kWesternAsia}},
{"TW", {Region::kAsia, Subregion::kEasternAsia}},
{"TJ", {Region::kAsia, Subregion::kCentralAsia}},
{"TZ", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"TH", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"TL", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"TG", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"TK", {Region::kOceania, Subregion::kOceania}},
{"TO", {Region::kOceania, Subregion::kOceania}},
{"TT", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"TN", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"TR", {Region::kAsia, Subregion::kWesternAsia}},
{"TM", {Region::kAsia, Subregion::kCentralAsia}},
{"TC", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"TV", {Region::kOceania, Subregion::kOceania}},
{"UG", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"UA", {Region::kEurope, Subregion::kEasternEurope}},
{"AE", {Region::kAsia, Subregion::kWesternAsia}},
{"GB", {Region::kEurope, Subregion::kNorthernEurope}},
{"US", {Region::kAmericas, Subregion::kNorthernAmerica}},
{"UM", {Region::kOceania, Subregion::kOceania}},
{"UY", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"UZ", {Region::kAsia, Subregion::kCentralAsia}},
{"VU", {Region::kOceania, Subregion::kOceania}},
{"VE", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"VN", {Region::kAsia, Subregion::kSoutheasternAsia}},
{"VG", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"VI", {Region::kAmericas, Subregion::kLatinAmericaAndTheCaribbean}},
{"WF", {Region::kOceania, Subregion::kOceania}},
{"EH", {Region::kAfrica, Subregion::kNorthernAfrica}},
{"YE", {Region::kAsia, Subregion::kWesternAsia}},
{"ZM", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
{"ZW", {Region::kAfrica, Subregion::kSubSaharanAfrica}},
});
inline constexpr auto kRegionToString =
base::MakeFixedFlatMap<Region, std::string_view>({
{Region::kAsia, "asia"},
{Region::kEurope, "europe"},
{Region::kAfrica, "africa"},
{Region::kOceania, "oceania"},
{Region::kAmericas, "americas"},
});
inline constexpr auto kSubregionToString =
base::MakeFixedFlatMap<Subregion, std::string_view>({
{Subregion::kSouthernAsia, "southern-asia"},
{Subregion::kNorthernEurope, "northern-europe"},
{Subregion::kSouthernEurope, "southern-europe"},
{Subregion::kNorthernAfrica, "northern-africa"},
{Subregion::kSubSaharanAfrica, "subsaharan-africa"},
{Subregion::kLatinAmericaAndTheCaribbean, "latin-america-caribbean"},
{Subregion::kWesternAsia, "western-asia"},
{Subregion::kWesternEurope, "western-europe"},
{Subregion::kEasternEurope, "eastern-europe"},
{Subregion::kNorthernAmerica, "northern-america"},
{Subregion::kSoutheasternAsia, "southeastern-asia"},
{Subregion::kEasternAsia, "eastern-asia"},
{Subregion::kOceania, "oceania"},
{Subregion::kCentralAsia, "central-asia"},
});
} // namespace
RegionIdentifiers GetRegionIdentifiers(std::string_view country_code) {
auto region_data = kCountryRegions.find(country_code);
if (region_data == kCountryRegions.end()) {
return {kOtherIdentifier, kOtherIdentifier};
}
auto region_str_it = kRegionToString.find(region_data->second.first);
auto subregion_str_it = kSubregionToString.find(region_data->second.second);
std::string_view region_str;
std::string_view subregion_str;
if (region_str_it == kRegionToString.end()) {
region_str = kOtherIdentifier;
} else {
region_str = region_str_it->second;
}
if (subregion_str_it == kSubregionToString.end()) {
subregion_str = kOtherIdentifier;
} else {
subregion_str = subregion_str_it->second;
}
return {region_str, subregion_str};
}
} // namespace p3a
+22
View File
@@ -0,0 +1,22 @@
/* Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_COMPONENTS_P3A_REGION_H_
#define BRAVE_COMPONENTS_P3A_REGION_H_
#include <string_view>
namespace p3a {
struct RegionIdentifiers {
std::string_view region;
std::string_view sub_region;
};
RegionIdentifiers GetRegionIdentifiers(std::string_view country_code);
} // namespace p3a
#endif // BRAVE_COMPONENTS_P3A_REGION_H_
+59
View File
@@ -0,0 +1,59 @@
/* Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/. */
#include "brave/components/p3a/region.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace p3a {
TEST(P3ARegionTest, GetRegionIdentifiers) {
// Test valid country codes
{
auto result = GetRegionIdentifiers("US");
EXPECT_EQ(result.region, "americas");
EXPECT_EQ(result.sub_region, "northern-america");
}
{
auto result = GetRegionIdentifiers("IN");
EXPECT_EQ(result.region, "asia");
EXPECT_EQ(result.sub_region, "southern-asia");
}
{
auto result = GetRegionIdentifiers("FR");
EXPECT_EQ(result.region, "europe");
EXPECT_EQ(result.sub_region, "western-europe");
}
{
auto result = GetRegionIdentifiers("AU");
EXPECT_EQ(result.region, "oceania");
EXPECT_EQ(result.sub_region, "oceania");
}
{
auto result = GetRegionIdentifiers("ZA");
EXPECT_EQ(result.region, "africa");
EXPECT_EQ(result.sub_region, "subsaharan-africa");
}
// Test invalid country code
{
auto result = GetRegionIdentifiers("XX");
EXPECT_EQ(result.region, "other");
EXPECT_EQ(result.sub_region, "other");
}
// Test empty country code
{
auto result = GetRegionIdentifiers("");
EXPECT_EQ(result.region, "other");
EXPECT_EQ(result.sub_region, "other");
}
}
} // namespace p3a