Skip to content

Commit

Permalink
Add refcode to select P3A Constellation metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
DJAndries committed Feb 26, 2024
1 parent 01c531b commit b5cc650
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 22 deletions.
6 changes: 5 additions & 1 deletion components/p3a/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static_library("p3a") {
deps += [ "//ios/web/public/thread" ]
} else {
deps += [
"//brave/components/brave_referrals/common",
"//content/public/browser",
"//content/public/common",
]
Expand Down Expand Up @@ -117,6 +118,9 @@ source_set("unit_tests") {
"//testing/gtest",
]
if (!is_ios) {
deps += [ "//content/test:test_support" ]
deps += [
"//brave/components/brave_referrals/common",
"//content/test:test_support",
]
}
}
64 changes: 63 additions & 1 deletion components/p3a/constellation_helper_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "brave/components/p3a/p3a_message.h"
#include "brave/components/p3a/star_randomness_test_util.h"
#include "brave/components/p3a/uploader.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "services/network/public/cpp/resource_request.h"
Expand All @@ -29,6 +30,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

#if !BUILDFLAG(IS_IOS)
#include "brave/components/brave_referrals/common/pref_names.h"
#endif // !BUILDFLAG(IS_IOS)

namespace p3a {

namespace {
Expand Down Expand Up @@ -59,6 +64,10 @@ class P3AConstellationHelperTest : public testing::Test {

ConstellationHelper::RegisterPrefs(local_state_.registry());

#if !BUILDFLAG(IS_IOS)
local_state_.registry()->RegisterStringPref(kReferralPromoCode, {});
#endif // !BUILDFLAG(IS_IOS)

url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) {
url_loader_factory_.ClearResponses();
Expand Down Expand Up @@ -244,7 +253,7 @@ TEST_F(P3AConstellationHelperTest, GenerateBasicMessage) {
helper_->StartMessagePreparation(
kTestHistogramName, log_type,
GenerateP3AConstellationMessage(kTestHistogramName, test_epoch,
meta_info, kP3AUploadType));
meta_info, kP3AUploadType, false));
task_environment_.RunUntilIdle();

CheckPointsRequestMade(log_type);
Expand All @@ -258,4 +267,57 @@ TEST_F(P3AConstellationHelperTest, GenerateBasicMessage) {
}
}

TEST_F(P3AConstellationHelperTest, IncludeRefcode) {
MessageMetainfo meta_info;
meta_info.Init(&local_state_, "release", "2022-01-01");

std::string message_with_no_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, false);
std::vector<std::string> no_refcode_layers = base::SplitString(
message_with_no_refcode, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
base::SplitResult::SPLIT_WANT_NONEMPTY);

EXPECT_EQ(no_refcode_layers.size(), 8U);
EXPECT_FALSE(base::StartsWith(no_refcode_layers.at(7), "ref"));

std::string message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true);
std::vector<std::string> refcode_layers = base::SplitString(
message_with_refcode, kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
base::SplitResult::SPLIT_WANT_NONEMPTY);

EXPECT_EQ(refcode_layers.size(), 9U);
EXPECT_EQ(refcode_layers.at(8), "ref|none");

#if !BUILDFLAG(IS_IOS)
local_state_.SetString(kReferralPromoCode, "BRV003");
meta_info.Init(&local_state_, "release", "2022-01-01");

message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true);
refcode_layers = base::SplitString(message_with_refcode,
kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
base::SplitResult::SPLIT_WANT_NONEMPTY);

EXPECT_EQ(refcode_layers.size(), 9U);
EXPECT_EQ(refcode_layers.at(8), "ref|BRV003");

local_state_.SetString(kReferralPromoCode, "ZRK009");
meta_info.Init(&local_state_, "release", "2022-01-01");

message_with_refcode = GenerateP3AConstellationMessage(
kTestHistogramName, 0, meta_info, kP3AUploadType, true);
refcode_layers = base::SplitString(message_with_refcode,
kP3AMessageConstellationLayerSeparator,
base::WhitespaceHandling::TRIM_WHITESPACE,
base::SplitResult::SPLIT_WANT_NONEMPTY);

EXPECT_EQ(refcode_layers.size(), 9U);
EXPECT_EQ(refcode_layers.at(8), "ref|other");
#endif // !BUILDFLAG(IS_IOS)
}

} // namespace p3a
4 changes: 3 additions & 1 deletion components/p3a/message_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,10 @@ std::string MessageManager::SerializeLog(std::string_view histogram_name,
message_meta_.Update();

if (is_constellation) {
bool include_refcode =
p3a::kHistogramsWithRefcodeIncluded.contains(histogram_name);
return GenerateP3AConstellationMessage(histogram_name, value, message_meta_,
upload_type);
upload_type, include_refcode);
} else {
base::Value::Dict p3a_json_value = GenerateP3AMessageDict(
histogram_name, value, log_type, message_meta_, upload_type);
Expand Down
9 changes: 9 additions & 0 deletions components/p3a/metric_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,15 @@ inline constexpr auto kConstellationOnlyHistograms =
"Brave.Core.PrimaryLang",
});

// 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,{
// TODO(djandries): Replace this metric with the first metric
// to include a refcode.
"Brave.ExampleMetric"
});

// clang-format on

} // namespace p3a
Expand Down
69 changes: 51 additions & 18 deletions components/p3a/p3a_message.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,34 @@
#include "brave/components/version_info/version_info.h"
#include "components/prefs/pref_service.h"

#if !BUILDFLAG(IS_IOS)
#include "brave/components/brave_referrals/common/pref_names.h"
#endif // !BUILDFLAG(IS_IOS)

namespace p3a {

namespace {
const char kMetricNameAttributeName[] = "metric_name";
const char kMetricValueAttributeName[] = "metric_value";
const char kPlatformAttributeName[] = "platform";
const char kChannelAttributeName[] = "channel";
const char kYosAttributeName[] = "yos";
const char kWosAttributeName[] = "wos";
const char kMosAttributeName[] = "mos";
const char kWoiAttributeName[] = "woi";
const char kYoiAttributeName[] = "yoi";
const char kCountryCodeAttributeName[] = "country_code";
const char kVersionAttributeName[] = "version";
const char kCadenceAttributeName[] = "cadence";

const char kSlowCadence[] = "slow";
const char kTypicalCadence[] = "typical";
const char kExpressCadence[] = "express";
constexpr char kMetricNameAttributeName[] = "metric_name";
constexpr char kMetricValueAttributeName[] = "metric_value";
constexpr char kPlatformAttributeName[] = "platform";
constexpr char kChannelAttributeName[] = "channel";
constexpr char kYosAttributeName[] = "yos";
constexpr char kWosAttributeName[] = "wos";
constexpr char kMosAttributeName[] = "mos";
constexpr char kWoiAttributeName[] = "woi";
constexpr char kYoiAttributeName[] = "yoi";
constexpr char kCountryCodeAttributeName[] = "country_code";
constexpr char kVersionAttributeName[] = "version";
constexpr char kCadenceAttributeName[] = "cadence";
constexpr char kRefAttributeName[] = "ref";

constexpr char kSlowCadence[] = "slow";
constexpr char kTypicalCadence[] = "typical";
constexpr char kExpressCadence[] = "express";

constexpr char kOrganicRefPrefix[] = "BRV";
constexpr char kRefNone[] = "none";
constexpr char kRefOther[] = "other";

} // namespace

Expand Down Expand Up @@ -123,7 +132,8 @@ base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
std::string GenerateP3AConstellationMessage(std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type) {
const std::string& upload_type,
bool include_refcode) {
base::Time::Exploded exploded;
meta.date_of_install.LocalExplode(&exploded);
DCHECK_GE(exploded.year, 999);
Expand Down Expand Up @@ -151,6 +161,10 @@ std::string GenerateP3AConstellationMessage(std::string_view metric_name,
}};
}

if (include_refcode) {
attributes.push_back({kRefAttributeName, meta.ref});
}

std::vector<std::string> serialized_attributes(attributes.size());

std::transform(attributes.begin(), attributes.end(),
Expand All @@ -166,9 +180,11 @@ std::string GenerateP3AConstellationMessage(std::string_view metric_name,
void MessageMetainfo::Init(PrefService* local_state,
std::string brave_channel,
std::string week_of_install) {
local_state_ = local_state;
platform = brave_stats::GetPlatformIdentifier();
channel = brave_channel;
InitVersion();
InitRef();

if (!week_of_install.empty()) {
date_of_install = brave_stats::GetYMDAsDate(week_of_install);
Expand All @@ -190,11 +206,12 @@ void MessageMetainfo::Init(PrefService* local_state,

VLOG(2) << "Message meta: " << platform << " " << channel << " " << version
<< " " << woi << " " << country_code_from_timezone << " "
<< country_code_from_locale;
<< country_code_from_locale << " " << ref;
}

void MessageMetainfo::Update() {
date_of_survey = base::Time::Now();
InitRef();
}

void MessageMetainfo::InitVersion() {
Expand All @@ -210,6 +227,22 @@ void MessageMetainfo::InitVersion() {
}
}

void MessageMetainfo::InitRef() {
std::string referral_code;
#if !BUILDFLAG(IS_IOS)
if (local_state_ && local_state_->HasPrefPath(kReferralPromoCode)) {
referral_code = local_state_->GetString(kReferralPromoCode);
}
#endif // !BUILDFLAG(IS_IOS)
if (referral_code.empty()) {
ref = kRefNone;
} else if (base::StartsWith(referral_code, kOrganicRefPrefix)) {
ref = referral_code;
} else {
ref = kRefOther;
}
}

void MessageMetainfo::MaybeStripCountry() {
constexpr char kCountryOther[] = "other";

Expand Down
9 changes: 8 additions & 1 deletion components/p3a/p3a_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,21 @@ 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_locale;
// May contain 'none', a 'BRV'-prefixed refcode, or 'other'.
std::string ref;

private:
// Used to report major/minor version numbers to reduce amount of
// Constellation tags
void InitVersion();

void InitRef();

// Ensures that country represent the big enough cohort that will not
// let anybody identify the sender.
void MaybeStripCountry();

raw_ptr<PrefService> local_state_ = nullptr;
};

base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
Expand All @@ -60,7 +66,8 @@ base::Value::Dict GenerateP3AMessageDict(std::string_view metric_name,
std::string GenerateP3AConstellationMessage(std::string_view metric_name,
uint64_t metric_value,
const MessageMetainfo& meta,
const std::string& upload_type);
const std::string& upload_type,
bool include_refcode);

} // namespace p3a

Expand Down

0 comments on commit b5cc650

Please sign in to comment.