Add metric configuration and alternative metric attributes
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace p3a {
|
||||
|
||||
inline constexpr char kCreativeMetricPrefix[] = "creativeInstanceId.";
|
||||
|
||||
+224
-314
@@ -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_
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user