0

Merge null and non-null aggregatable report structs

Null aggregatable reports are just a special case of aggregatable
reports, so this eliminates various redundant code paths.

This CL contains no intentional user-visible behavioral changes.

BYPASS_LARGE_CHANGE_WARNING=refactoring change with net-negative LoC

Change-Id: I3d0433297b831207174887587bbfdf8b5be0a90e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5709639
Commit-Queue: Andrew Paseltiner <apaseltiner@chromium.org>
Reviewed-by: Nan Lin <linnan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1373514}
This commit is contained in:
Andrew Paseltiner
2024-10-24 19:45:32 +00:00
committed by Chromium LUCI CQ
parent 4462cb1428
commit 64c97f1d9a
15 changed files with 393 additions and 505 deletions

@ -17,7 +17,6 @@
#include "base/feature_list.h"
#include "base/functional/overloaded.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/clamped_math.h"
#include "base/numerics/safe_conversions.h"
@ -177,29 +176,12 @@ CreateAggregatableHistogram(
std::optional<AggregatableReportRequest> CreateAggregatableReportRequest(
const AttributionReport& report) {
base::Time source_time;
const AttributionReport::CommonAggregatableData* common_aggregatable_data =
nullptr;
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions;
const auto* aggregatable_data =
absl::get_if<AttributionReport::AggregatableData>(&report.data());
DCHECK(aggregatable_data);
absl::visit(
base::Overloaded{
[](const AttributionReport::EventLevelData&) {
NOTREACHED_IN_MIGRATION();
},
[&](const AttributionReport::AggregatableAttributionData& data) {
source_time = data.source_time;
common_aggregatable_data = &data.common_data;
contributions = data.contributions;
},
[&](const AttributionReport::NullAggregatableData& data) {
source_time = data.fake_source_time;
common_aggregatable_data = &data.common_data;
},
},
report.data());
DCHECK(common_aggregatable_data);
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions = aggregatable_data->contributions();
const AttributionInfo& attribution_info = report.attribution_info();
@ -209,12 +191,12 @@ std::optional<AggregatableReportRequest> CreateAggregatableReportRequest(
: AggregatableReportSharedInfo::DebugMode::kDisabled;
base::Value::Dict additional_fields;
switch (common_aggregatable_data->aggregatable_trigger_config
switch (aggregatable_data->aggregatable_trigger_config()
.source_registration_time_config()) {
case attribution_reporting::mojom::SourceRegistrationTimeConfig::kInclude:
additional_fields.Set(
"source_registration_time",
SerializeTimeRoundedDownToWholeDayInSeconds(source_time));
additional_fields.Set("source_registration_time",
SerializeTimeRoundedDownToWholeDayInSeconds(
aggregatable_data->source_time()));
break;
case attribution_reporting::mojom::SourceRegistrationTimeConfig::kExclude:
break;
@ -225,10 +207,9 @@ std::optional<AggregatableReportRequest> CreateAggregatableReportRequest(
std::optional<size_t> filtering_id_max_bytes;
if (IsAggregatableFilteringIdsEnabled()) {
filtering_id_max_bytes =
common_aggregatable_data->aggregatable_trigger_config
.aggregatable_filtering_id_max_bytes()
.value();
filtering_id_max_bytes = aggregatable_data->aggregatable_trigger_config()
.aggregatable_filtering_id_max_bytes()
.value();
} else {
// We clear the filtering ids to avoid hitting `FilteringIdsFitInMaxBytes()`
// invalidly in case that filtering ids were unexpectedly set in the db for
@ -242,9 +223,9 @@ std::optional<AggregatableReportRequest> CreateAggregatableReportRequest(
AggregationServicePayloadContents::Operation::kHistogram,
std::move(contributions),
blink::mojom::AggregationServiceMode::kDefault,
common_aggregatable_data->aggregation_coordinator_origin
aggregatable_data->aggregation_coordinator_origin()
? std::make_optional(
**common_aggregatable_data->aggregation_coordinator_origin)
**aggregatable_data->aggregation_coordinator_origin())
: std::nullopt,
/*max_contributions_allowed=*/
attribution_reporting::kMaxAggregationKeysPerSource,
@ -253,10 +234,10 @@ std::optional<AggregatableReportRequest> CreateAggregatableReportRequest(
report.initial_report_time(), report.external_report_id(),
report.reporting_origin(), debug_mode, std::move(additional_fields),
filtering_id_max_bytes.has_value()
? AttributionReport::CommonAggregatableData::
? AttributionReport::AggregatableData::
kVersionWithFlexibleContributionFiltering
: AttributionReport::CommonAggregatableData::kVersion,
AttributionReport::CommonAggregatableData::kApiIdentifier),
: AttributionReport::AggregatableData::kVersion,
AttributionReport::AggregatableData::kApiIdentifier),
// The returned request cannot be serialized due to the null `delay_type`.
/*delay_type=*/std::nullopt);
}

@ -340,16 +340,10 @@ class AttributionAggregatableReportGoldenLatestVersionTest
ASSERT_TRUE(request);
const auto get_report_body = [&](AggregatableReport assembled_report) {
auto* data = absl::get_if<AttributionReport::AggregatableAttributionData>(
&report.data());
if (data) {
data->common_data.assembled_report = std::move(assembled_report);
} else {
auto* null_data = absl::get_if<AttributionReport::NullAggregatableData>(
&report.data());
CHECK(null_data);
null_data->common_data.assembled_report = std::move(assembled_report);
}
auto* data =
absl::get_if<AttributionReport::AggregatableData>(&report.data());
CHECK(data);
data->SetAssembledReport(std::move(assembled_report));
return report.ReportBody();
};

@ -165,48 +165,37 @@ attribution_internals::mojom::WebUIReportPtr WebUIReport(
event_level_data.attributed_truthfully));
},
[](const AttributionReport::AggregatableAttributionData&
aggregatable_data) {
[](const AttributionReport::AggregatableData& aggregatable_data) {
std::vector<ai_mojom::AggregatableHistogramContributionPtr>
contributions;
base::ranges::transform(
aggregatable_data.contributions,
std::back_inserter(contributions),
[](const auto& contribution) {
return ai_mojom::AggregatableHistogramContribution::New(
attribution_reporting::HexEncodeAggregationKey(
contribution.bucket),
base::checked_cast<uint32_t>(contribution.value),
contribution.filtering_id.value_or(0));
});
if (aggregatable_data.is_null()) {
contributions.push_back(
ai_mojom::AggregatableHistogramContribution::New(
attribution_reporting::HexEncodeAggregationKey(0),
/*value=*/0,
/*filtering_id=*/0));
} else {
base::ranges::transform(
aggregatable_data.contributions(),
std::back_inserter(contributions),
[](const auto& contribution) {
return ai_mojom::AggregatableHistogramContribution::New(
attribution_reporting::HexEncodeAggregationKey(
contribution.bucket),
base::checked_cast<uint32_t>(contribution.value),
contribution.filtering_id.value_or(0));
});
}
return ai_mojom::WebUIReportData::NewAggregatableAttributionData(
ai_mojom::WebUIReportAggregatableAttributionData::New(
std::move(contributions),
aggregatable_data.common_data.aggregation_coordinator_origin
? aggregatable_data.common_data
.aggregation_coordinator_origin->Serialize()
: "",
/*is_null_report=*/false));
},
[](const AttributionReport::NullAggregatableData& null_data)
-> ai_mojom::WebUIReportDataPtr {
std::vector<ai_mojom::AggregatableHistogramContributionPtr>
contributions;
contributions.push_back(
ai_mojom::AggregatableHistogramContribution::New(
attribution_reporting::HexEncodeAggregationKey(0),
/*value=*/0,
/*filtering_id=*/0));
return ai_mojom::WebUIReportData::NewAggregatableAttributionData(
ai_mojom::WebUIReportAggregatableAttributionData::New(
std::move(contributions),
null_data.common_data.aggregation_coordinator_origin
? null_data.common_data.aggregation_coordinator_origin
aggregatable_data.aggregation_coordinator_origin()
? aggregatable_data.aggregation_coordinator_origin()
->Serialize()
: "",
/*is_null_report=*/true));
aggregatable_data.is_null()));
},
},
report.data());

@ -377,7 +377,11 @@ void LogMetricsOnReportSend(const AttributionReport& report, base::Time now) {
now - report.report_time(),
base::Seconds(1), base::Days(1), 50);
},
[&](const AttributionReport::AggregatableAttributionData& data) {
[&](const AttributionReport::AggregatableData& data) {
if (data.is_null()) {
return;
}
base::TimeDelta time_from_conversion_to_report_assembly =
report.report_time() - report.attribution_info().time;
UMA_HISTOGRAM_CUSTOM_TIMES(
@ -388,7 +392,7 @@ void LogMetricsOnReportSend(const AttributionReport& report, base::Time now) {
LogAggregatableReportHistogramCustomTimes(
"ExtraReportDelay",
data.common_data.aggregatable_trigger_config
data.aggregatable_trigger_config()
.trigger_context_id()
.has_value(),
now - report.initial_report_time(), base::Seconds(1),
@ -399,7 +403,6 @@ void LogMetricsOnReportSend(const AttributionReport& report, base::Time now) {
now - report.report_time(), base::Seconds(1), base::Days(1),
50);
},
[](const AttributionReport::NullAggregatableData&) {},
},
report.data());
}
@ -1304,17 +1307,10 @@ void AttributionManagerImpl::OnAggregatableReportAssembled(
return;
}
absl::visit(
base::Overloaded{
[](const AttributionReport::EventLevelData&) { NOTREACHED(); },
[&](AttributionReport::AggregatableAttributionData& data) {
data.common_data.assembled_report = std::move(assembled_report);
},
[&](AttributionReport::NullAggregatableData& data) {
data.common_data.assembled_report = std::move(assembled_report);
},
},
report.data());
auto* data =
absl::get_if<AttributionReport::AggregatableData>(&report.data());
CHECK(data);
data->SetAssembledReport(std::move(assembled_report));
RecordAssembleAggregatableReportStatus(
AssembleAggregatableReportStatus::kSuccess);

@ -37,8 +37,8 @@ namespace {
using ::attribution_reporting::SuitableOrigin;
void PopulateReportBody(base::Value::Dict& dict,
const AttributionReport::CommonAggregatableData& data) {
if (const auto& assembled_report = data.assembled_report;
const AttributionReport::AggregatableData& data) {
if (const auto& assembled_report = data.assembled_report();
assembled_report.has_value()) {
dict = assembled_report->GetAsJson();
} else {
@ -49,7 +49,7 @@ void PopulateReportBody(base::Value::Dict& dict,
}
if (const auto& trigger_context_id =
data.aggregatable_trigger_config.trigger_context_id();
data.aggregatable_trigger_config().trigger_context_id();
trigger_context_id.has_value()) {
dict.Set("trigger_context_id", *trigger_context_id);
}
@ -66,7 +66,6 @@ AttributionReport::EventLevelData::EventLevelData(uint32_t trigger_data,
destinations(source.destination_sites()),
source_event_id(source.source_event_id()),
source_type(source.common_info().source_type()),
source_debug_key(source.debug_key()),
randomized_response_rate(source.randomized_response_rate()),
attributed_truthfully(source.attribution_logic() ==
StoredSource::AttributionLogic::kTruthfully) {}
@ -84,92 +83,67 @@ AttributionReport::EventLevelData& AttributionReport::EventLevelData::operator=(
AttributionReport::EventLevelData::~EventLevelData() = default;
AttributionReport::CommonAggregatableData::CommonAggregatableData(
AttributionReport::AggregatableData::AggregatableData(
std::optional<SuitableOrigin> aggregation_coordinator_origin,
attribution_reporting::AggregatableTriggerConfig
aggregatable_trigger_config)
: aggregation_coordinator_origin(std::move(aggregation_coordinator_origin)),
aggregatable_trigger_config(std::move(aggregatable_trigger_config)) {}
AttributionReport::CommonAggregatableData::CommonAggregatableData(
const CommonAggregatableData&) = default;
AttributionReport::CommonAggregatableData&
AttributionReport::CommonAggregatableData::operator=(
const CommonAggregatableData&) = default;
AttributionReport::CommonAggregatableData::CommonAggregatableData(
CommonAggregatableData&&) = default;
AttributionReport::CommonAggregatableData&
AttributionReport::CommonAggregatableData::operator=(CommonAggregatableData&&) =
default;
AttributionReport::CommonAggregatableData::~CommonAggregatableData() = default;
AttributionReport::AggregatableAttributionData::AggregatableAttributionData(
CommonAggregatableData common_data,
aggregatable_trigger_config,
base::Time source_time,
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions,
const StoredSource& source)
: common_data(std::move(common_data)),
contributions(std::move(contributions)),
source_time(source.source_time()),
source_debug_key(source.debug_key()),
source_origin(source.common_info().source_origin()) {}
AttributionReport::AggregatableAttributionData::AggregatableAttributionData(
const AggregatableAttributionData&) = default;
AttributionReport::AggregatableAttributionData&
AttributionReport::AggregatableAttributionData::operator=(
const AggregatableAttributionData&) = default;
AttributionReport::AggregatableAttributionData::AggregatableAttributionData(
AggregatableAttributionData&&) = default;
AttributionReport::AggregatableAttributionData&
AttributionReport::AggregatableAttributionData::operator=(
AggregatableAttributionData&&) = default;
AttributionReport::AggregatableAttributionData::~AggregatableAttributionData() =
default;
base::CheckedNumeric<int64_t>
AttributionReport::AggregatableAttributionData::BudgetRequired() const {
return GetTotalAggregatableValues(contributions);
std::optional<attribution_reporting::SuitableOrigin> source_origin)
: aggregation_coordinator_origin_(
std::move(aggregation_coordinator_origin)),
aggregatable_trigger_config_(std::move(aggregatable_trigger_config)),
source_time_(source_time),
contributions_(std::move(contributions)),
source_origin_(std::move(source_origin)) {
CHECK(source_origin_.has_value() || contributions_.empty());
}
AttributionReport::NullAggregatableData::NullAggregatableData(
CommonAggregatableData common_data,
base::Time fake_source_time)
: common_data(std::move(common_data)),
fake_source_time(fake_source_time) {}
AttributionReport::NullAggregatableData::NullAggregatableData(
const NullAggregatableData&) = default;
AttributionReport::NullAggregatableData::NullAggregatableData(
NullAggregatableData&&) = default;
AttributionReport::NullAggregatableData&
AttributionReport::NullAggregatableData::operator=(
const NullAggregatableData&) = default;
AttributionReport::NullAggregatableData&
AttributionReport::NullAggregatableData::operator=(NullAggregatableData&&) =
AttributionReport::AggregatableData::AggregatableData(const AggregatableData&) =
default;
AttributionReport::NullAggregatableData::~NullAggregatableData() = default;
AttributionReport::AggregatableData&
AttributionReport::AggregatableData::operator=(const AggregatableData&) =
default;
AttributionReport::AttributionReport(AttributionInfo attribution_info,
Id id,
base::Time report_time,
base::Time initial_report_time,
base::Uuid external_report_id,
int failed_send_attempts,
Data data,
SuitableOrigin reporting_origin)
AttributionReport::AggregatableData::AggregatableData(AggregatableData&&) =
default;
AttributionReport::AggregatableData&
AttributionReport::AggregatableData::operator=(AggregatableData&&) = default;
void AttributionReport::AggregatableData::SetContributions(
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions) {
CHECK(source_origin_.has_value());
CHECK(!contributions.empty());
contributions_ = std::move(contributions);
}
void AttributionReport::AggregatableData::SetAssembledReport(
std::optional<AggregatableReport> assembled_report) {
DCHECK(!assembled_report_.has_value());
assembled_report_ = std::move(assembled_report);
}
AttributionReport::AggregatableData::~AggregatableData() = default;
base::CheckedNumeric<int64_t>
AttributionReport::AggregatableData::BudgetRequired() const {
return GetTotalAggregatableValues(contributions_);
}
AttributionReport::AttributionReport(
AttributionInfo attribution_info,
Id id,
base::Time report_time,
base::Time initial_report_time,
base::Uuid external_report_id,
int failed_send_attempts,
Data data,
attribution_reporting::SuitableOrigin reporting_origin,
std::optional<uint64_t> source_debug_key)
: attribution_info_(std::move(attribution_info)),
id_(id),
report_time_(report_time),
@ -177,7 +151,8 @@ AttributionReport::AttributionReport(AttributionInfo attribution_info,
external_report_id_(std::move(external_report_id)),
failed_send_attempts_(failed_send_attempts),
data_(std::move(data)),
reporting_origin_(std::move(reporting_origin)) {
reporting_origin_(std::move(reporting_origin)),
source_debug_key_(source_debug_key) {
DCHECK(external_report_id_.is_valid());
DCHECK_GE(failed_send_attempts_, 0);
}
@ -250,28 +225,37 @@ base::Value::Dict AttributionReport::ReportBody() const {
.InSeconds()));
},
[&](const AggregatableAttributionData& data) {
PopulateReportBody(dict, data.common_data);
},
[&](const NullAggregatableData& data) {
PopulateReportBody(dict, data.common_data);
},
[&](const AggregatableData& data) { PopulateReportBody(dict, data); },
},
data_);
if (CanDebuggingBeEnabled()) {
std::optional<uint64_t> source_debug_key = GetSourceDebugKey();
CHECK(source_debug_key.has_value());
CHECK(source_debug_key_.has_value());
std::optional<uint64_t> trigger_debug_key = attribution_info_.debug_key;
CHECK(trigger_debug_key.has_value());
dict.Set("source_debug_key", base::NumberToString(*source_debug_key));
dict.Set("source_debug_key", base::NumberToString(*source_debug_key_));
dict.Set("trigger_debug_key", base::NumberToString(*trigger_debug_key));
}
return dict;
}
AttributionReport::Type AttributionReport::GetReportType() const {
return absl::visit(
base::Overloaded{
[](const EventLevelData&) {
return AttributionReport::Type::kEventLevel;
},
[](const AggregatableData& data) {
return data.is_null()
? AttributionReport::Type::kNullAggregatable
: AttributionReport::Type::kAggregatableAttribution;
},
},
data_);
}
void AttributionReport::set_report_time(base::Time report_time) {
report_time_ = report_time;
}
@ -291,29 +275,16 @@ std::optional<base::Time> AttributionReport::MinReportTime(
return std::min(*a, *b);
}
std::optional<uint64_t> AttributionReport::GetSourceDebugKey() const {
return absl::visit(
base::Overloaded{
[](const EventLevelData& data) { return data.source_debug_key; },
[](const AggregatableAttributionData& data) {
return data.source_debug_key;
},
[](const NullAggregatableData& data) {
return std::optional<uint64_t>();
},
},
data_);
}
const SuitableOrigin& AttributionReport::GetSourceOrigin() const {
return absl::visit(
base::Overloaded{
[](const AttributionReport::EventLevelData& data)
-> const SuitableOrigin& { return data.source_origin; },
[](const AttributionReport::AggregatableAttributionData& data)
-> const SuitableOrigin& { return data.source_origin; },
[&](const AttributionReport::NullAggregatableData&)
[&](const AttributionReport::AggregatableData& data)
-> const SuitableOrigin& {
if (data.source_origin().has_value()) {
return *data.source_origin();
}
return attribution_info_.context_origin;
},
},
@ -322,7 +293,7 @@ const SuitableOrigin& AttributionReport::GetSourceOrigin() const {
bool AttributionReport::CanDebuggingBeEnabled() const {
return attribution_info_.debug_key.has_value() &&
GetSourceDebugKey().has_value();
source_debug_key_.has_value();
}
} // namespace content

@ -63,7 +63,6 @@ class CONTENT_EXPORT AttributionReport {
attribution_reporting::DestinationSet destinations;
uint64_t source_event_id;
attribution_reporting::mojom::SourceType source_type;
std::optional<uint64_t> source_debug_key;
double randomized_response_rate;
bool attributed_truthfully;
@ -71,15 +70,21 @@ class CONTENT_EXPORT AttributionReport {
const EventLevelData&) = default;
};
struct CONTENT_EXPORT CommonAggregatableData {
CommonAggregatableData(std::optional<attribution_reporting::SuitableOrigin>
aggregation_coordinator_origin,
attribution_reporting::AggregatableTriggerConfig);
CommonAggregatableData(const CommonAggregatableData&);
CommonAggregatableData(CommonAggregatableData&&);
CommonAggregatableData& operator=(const CommonAggregatableData&);
CommonAggregatableData& operator=(CommonAggregatableData&&);
~CommonAggregatableData();
class CONTENT_EXPORT AggregatableData {
public:
AggregatableData(
std::optional<attribution_reporting::SuitableOrigin>
aggregation_coordinator_origin,
attribution_reporting::AggregatableTriggerConfig,
base::Time source_time,
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions,
std::optional<attribution_reporting::SuitableOrigin> source_origin);
AggregatableData(const AggregatableData&);
AggregatableData(AggregatableData&&);
AggregatableData& operator=(const AggregatableData&);
AggregatableData& operator=(AggregatableData&&);
~AggregatableData();
// When updating the string, update the goldens and version history too, see
// //content/test/data/attribution_reporting/aggregatable_report_goldens/README.md
@ -89,68 +94,65 @@ class CONTENT_EXPORT AttributionReport {
// Enum string identifying this API for use in reports.
static constexpr char kApiIdentifier[] = "attribution-reporting";
// The report assembled by the aggregation service. If null, the report has
// not been assembled yet.
std::optional<AggregatableReport> assembled_report;
const std::optional<AggregatableReport>& assembled_report() const {
return assembled_report_;
}
std::optional<attribution_reporting::SuitableOrigin>
aggregation_coordinator_origin;
void SetAssembledReport(std::optional<AggregatableReport>);
attribution_reporting::AggregatableTriggerConfig
aggregatable_trigger_config;
const std::optional<attribution_reporting::SuitableOrigin>&
aggregation_coordinator_origin() const {
return aggregation_coordinator_origin_;
}
// When adding new members, the corresponding `operator==()` definition in
// `attribution_test_utils.h` should also be updated.
};
const attribution_reporting::AggregatableTriggerConfig&
aggregatable_trigger_config() const {
return aggregatable_trigger_config_;
}
// Struct that contains the data specific to the aggregatable report.
struct CONTENT_EXPORT AggregatableAttributionData {
AggregatableAttributionData(
CommonAggregatableData,
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions,
const StoredSource&);
AggregatableAttributionData(const AggregatableAttributionData&);
AggregatableAttributionData& operator=(const AggregatableAttributionData&);
AggregatableAttributionData(AggregatableAttributionData&&);
AggregatableAttributionData& operator=(AggregatableAttributionData&&);
~AggregatableAttributionData();
base::Time source_time() const { return source_time_; }
const std::vector<blink::mojom::AggregatableReportHistogramContribution>&
contributions() const {
return contributions_;
}
void SetContributions(
std::vector<blink::mojom::AggregatableReportHistogramContribution>);
const std::optional<attribution_reporting::SuitableOrigin>& source_origin()
const {
return source_origin_;
}
// Returns the sum of the contributions (values) across all buckets.
base::CheckedNumeric<int64_t> BudgetRequired() const;
CommonAggregatableData common_data;
bool is_null() const { return !source_origin_.has_value(); }
private:
// The report assembled by the aggregation service. If null, the report has
// not been assembled yet.
std::optional<AggregatableReport> assembled_report_;
std::optional<attribution_reporting::SuitableOrigin>
aggregation_coordinator_origin_;
attribution_reporting::AggregatableTriggerConfig
aggregatable_trigger_config_;
base::Time source_time_;
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions;
contributions_;
base::Time source_time;
std::optional<uint64_t> source_debug_key;
attribution_reporting::SuitableOrigin source_origin;
std::optional<attribution_reporting::SuitableOrigin> source_origin_;
// When adding new members, the corresponding `operator==()` definition in
// `attribution_test_utils.h` should also be updated.
};
struct CONTENT_EXPORT NullAggregatableData {
NullAggregatableData(CommonAggregatableData,
base::Time fake_source_time);
NullAggregatableData(const NullAggregatableData&);
NullAggregatableData(NullAggregatableData&&);
NullAggregatableData& operator=(const NullAggregatableData&);
NullAggregatableData& operator=(NullAggregatableData&&);
~NullAggregatableData();
CommonAggregatableData common_data;
base::Time fake_source_time;
// When adding new members, the corresponding `operator==()` definition in
// `attribution_test_utils.h` should also be updated.
};
using Data = absl::variant<EventLevelData,
AggregatableAttributionData,
NullAggregatableData>;
using Data = absl::variant<EventLevelData, AggregatableData>;
// Returns the minimum non-null time of `a` and `b`, or `std::nullopt` if
// both are null.
@ -164,7 +166,8 @@ class CONTENT_EXPORT AttributionReport {
base::Uuid external_report_id,
int failed_send_attempts,
Data data,
attribution_reporting::SuitableOrigin reporting_origin);
attribution_reporting::SuitableOrigin reporting_origin,
std::optional<uint64_t> source_debug_key);
AttributionReport(const AttributionReport&);
AttributionReport& operator=(const AttributionReport&);
AttributionReport(AttributionReport&&);
@ -192,9 +195,9 @@ class CONTENT_EXPORT AttributionReport {
Data& data() { return data_; }
Type GetReportType() const { return static_cast<Type>(data_.index()); }
Type GetReportType() const;
std::optional<uint64_t> GetSourceDebugKey() const;
std::optional<uint64_t> source_debug_key() const { return source_debug_key_; }
const attribution_reporting::SuitableOrigin& reporting_origin() const {
return reporting_origin_;
@ -235,6 +238,8 @@ class CONTENT_EXPORT AttributionReport {
attribution_reporting::SuitableOrigin reporting_origin_;
std::optional<uint64_t> source_debug_key_;
// When adding new members, the corresponding `operator==()` definition in
// `attribution_test_utils.h` should also be updated.
};

@ -257,35 +257,32 @@ void AttributionReportNetworkSender::OnReportSent(
has_trigger_context_id, *retry_succeed);
}
},
[&](const AttributionReport::AggregatableAttributionData& data) {
has_trigger_context_id =
data.common_data.aggregatable_trigger_config
.trigger_context_id()
.has_value();
NetworkHistogram("ReportStatusAggregatable",
&base::UmaHistogramEnumeration, is_debug_report,
has_trigger_context_id, status);
NetworkHistogram("HttpResponseOrNetErrorCodeAggregatable",
&base::UmaHistogramSparse, is_debug_report,
has_trigger_context_id, response_or_net_error);
if (retry_succeed.has_value()) {
NetworkHistogram("ReportRetrySucceedAggregatable",
&base::UmaHistogramBoolean, is_debug_report,
has_trigger_context_id, *retry_succeed);
[&](const AttributionReport::AggregatableData& data) {
has_trigger_context_id = data.aggregatable_trigger_config()
.trigger_context_id()
.has_value();
if (data.is_null()) {
NetworkHistogram("ReportStatusAggregatableNull",
&base::UmaHistogramEnumeration, is_debug_report,
has_trigger_context_id, status);
NetworkHistogram("HttpResponseOrNetErrorCodeAggregatableNull",
&base::UmaHistogramSparse, is_debug_report,
has_trigger_context_id, response_or_net_error);
} else {
NetworkHistogram("ReportStatusAggregatable",
&base::UmaHistogramEnumeration, is_debug_report,
has_trigger_context_id, status);
NetworkHistogram("HttpResponseOrNetErrorCodeAggregatable",
&base::UmaHistogramSparse, is_debug_report,
has_trigger_context_id, response_or_net_error);
if (retry_succeed.has_value()) {
NetworkHistogram("ReportRetrySucceedAggregatable",
&base::UmaHistogramBoolean, is_debug_report,
has_trigger_context_id, *retry_succeed);
}
}
},
[&](const AttributionReport::NullAggregatableData& data) {
has_trigger_context_id =
data.common_data.aggregatable_trigger_config
.trigger_context_id()
.has_value();
NetworkHistogram("ReportStatusAggregatableNull",
&base::UmaHistogramEnumeration, is_debug_report,
has_trigger_context_id, status);
NetworkHistogram("HttpResponseOrNetErrorCodeAggregatableNull",
&base::UmaHistogramSparse, is_debug_report,
has_trigger_context_id, response_or_net_error);
},
},
report.data());

@ -262,9 +262,8 @@ TEST(AttributionReportTest, NullAggregatableReport) {
GURL("https://report.test/.well-known/attribution-reporting/"
"report-aggregate-attribution"));
auto& data =
absl::get<AttributionReport::NullAggregatableData>(report.data());
data.common_data.assembled_report =
auto& data = absl::get<AttributionReport::AggregatableData>(report.data());
data.SetAssembledReport(
AggregatableReport({AggregatableReport::AggregationServicePayload(
/*payload=*/kABCD1234AsBytes,
/*key_id=*/"key",
@ -272,7 +271,7 @@ TEST(AttributionReportTest, NullAggregatableReport) {
"example_shared_info",
/*debug_key=*/std::nullopt,
/*additional_fields=*/{},
/*aggregation_coordinator_origin=*/std::nullopt);
/*aggregation_coordinator_origin=*/std::nullopt));
EXPECT_THAT(report.ReportBody(), IsJson(expected));
}
@ -304,9 +303,8 @@ TEST(AttributionReportTest, ReportBody_AggregatableAttributionReport) {
/*bucket=*/1, /*value=*/2, /*filtering_id=*/std::nullopt)})
.BuildAggregatableAttribution();
auto& data =
absl::get<AttributionReport::AggregatableAttributionData>(report.data());
data.common_data.assembled_report =
auto& data = absl::get<AttributionReport::AggregatableData>(report.data());
data.SetAssembledReport(
AggregatableReport({AggregatableReport::AggregationServicePayload(
/*payload=*/kABCD1234AsBytes,
/*key_id=*/"key",
@ -314,7 +312,7 @@ TEST(AttributionReportTest, ReportBody_AggregatableAttributionReport) {
"example_shared_info",
/*debug_key=*/std::nullopt,
/*additional_fields=*/{},
/*aggregation_coordinator_origin=*/std::nullopt);
/*aggregation_coordinator_origin=*/std::nullopt));
EXPECT_THAT(report.ReportBody(), IsJson(expected));
}

@ -155,7 +155,7 @@ enum class DebugKeyUsage {
// LINT.ThenChange(//tools/metrics/histograms/metadata/attribution_reporting/enums.xml:ConversionReportDebugKeyUsage)
void RecordDebugKeyUsage(const AttributionReport& report) {
bool has_source_debug_key = report.GetSourceDebugKey().has_value();
bool has_source_debug_key = report.source_debug_key().has_value();
bool has_trigger_debug_key = report.attribution_info().debug_key.has_value();
DebugKeyUsage usage = DebugKeyUsage::kNone;
@ -904,7 +904,7 @@ EventLevelResult AttributionResolverImpl::MaybeCreateEventLevelReport(
/*failed_send_attempts=*/0,
AttributionReport::EventLevelData(trigger_data, event_trigger->priority,
source),
common_info.reporting_origin());
common_info.reporting_origin(), source.debug_key());
dedup_key = event_trigger->dedup_key;
@ -993,12 +993,12 @@ AttributionResolverImpl::MaybeCreateAggregatableAttributionReport(
attribution_info, AttributionReport::Id(kUnsetRecordId), report_time,
/*initial_report_time=*/report_time, delegate_->NewReportID(),
/*failed_send_attempts=*/0,
AttributionReport::AggregatableAttributionData(
AttributionReport::CommonAggregatableData(
trigger_registration.aggregation_coordinator_origin,
trigger_registration.aggregatable_trigger_config),
std::move(contributions), source),
source.common_info().reporting_origin());
AttributionReport::AggregatableData(
trigger_registration.aggregation_coordinator_origin,
trigger_registration.aggregatable_trigger_config,
source.source_time(), std::move(contributions),
source.common_info().source_origin()),
source.common_info().reporting_origin(), source.debug_key());
return AggregatableResult::kSuccess;
}
@ -1012,11 +1012,11 @@ bool AttributionResolverImpl::GenerateNullAggregatableReportsAndStoreReports(
std::optional<base::Time> attributed_source_time;
if (new_aggregatable_report) {
const auto* data =
absl::get_if<AttributionReport::AggregatableAttributionData>(
&new_aggregatable_report->data());
const auto* data = absl::get_if<AttributionReport::AggregatableData>(
&new_aggregatable_report->data());
DCHECK(data);
attributed_source_time = data->source_time;
DCHECK(!data->is_null());
attributed_source_time = data->source_time();
DCHECK(source);
@ -1027,8 +1027,8 @@ bool AttributionResolverImpl::GenerateNullAggregatableReportsAndStoreReports(
new_aggregatable_report->external_report_id(),
attribution_info.debug_key, attribution_info.context_origin,
new_aggregatable_report->reporting_origin(),
data->common_data.aggregation_coordinator_origin,
data->common_data.aggregatable_trigger_config, data->contributions);
data->aggregation_coordinator_origin(),
data->aggregatable_trigger_config(), data->contributions());
if (!report_id.has_value()) {
return false;

@ -165,6 +165,10 @@ MATCHER_P(CreateReportMaxAggregatableReportsLimitIs, matcher, "") {
return ExplainMatchResult(matcher, value, result_listener);
}
MATCHER_P(SourceTimeIs, matcher, "") {
return ExplainMatchResult(matcher, arg.source_time(), result_listener);
}
} // namespace
// Unit test suite for the AttributionResolver interface. All
@ -4190,24 +4194,21 @@ TEST_F(AttributionResolverTest,
EXPECT_THAT(result.min_null_aggregatable_report_time(),
Optional(now + kReportDelay));
EXPECT_THAT(
storage()->GetAttributionReports(base::Time::Max()),
UnorderedElementsAre(
AggregatableAttributionDataIs(SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude)),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now - base::Days(1)))),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now - base::Days(30))))));
EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
UnorderedElementsAre(
AggregatableAttributionDataIs(SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude)),
NullAggregatableDataIs(
AllOf(SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude),
SourceTimeIs(now - base::Days(1)))),
NullAggregatableDataIs(
AllOf(SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude),
SourceTimeIs(now - base::Days(30))))));
}
TEST_F(
@ -4229,25 +4230,21 @@ TEST_F(
EXPECT_THAT(
storage()->GetAttributionReports(base::Time::Max()),
UnorderedElementsAre(
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now))),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now - base::Days(1)))),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kInclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now - base::Days(30))))));
UnorderedElementsAre(NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude),
SourceTimeIs(now))),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude),
SourceTimeIs(now - base::Days(1)))),
NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kInclude),
SourceTimeIs(now - base::Days(30))))));
}
TEST_F(
@ -4291,14 +4288,12 @@ TEST_F(
EXPECT_THAT(result.min_null_aggregatable_report_time(),
Optional(now + kReportDelay));
EXPECT_THAT(
storage()->GetAttributionReports(base::Time::Max()),
UnorderedElementsAre(NullAggregatableDataIs(AllOf(
SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::SourceRegistrationTimeConfig::
kExclude),
Field(&AttributionReport::NullAggregatableData::fake_source_time,
now)))));
EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
UnorderedElementsAre(NullAggregatableDataIs(
AllOf(SourceRegistrationTimeConfigIs(
attribution_reporting::mojom::
SourceRegistrationTimeConfig::kExclude),
SourceTimeIs(now)))));
}
TEST_F(AttributionResolverTest,

@ -1297,6 +1297,7 @@ AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) {
}
std::optional<AttributionReport::Data> data;
std::optional<uint64_t> source_debug_key;
switch (base::span<const uint8_t> metadata = statement.ColumnBlob(col++);
*report_type) {
@ -1310,6 +1311,7 @@ AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) {
if (!data.has_value()) {
corruptions.status_set.Put(ReportCorruptionStatus::kInvalidMetadata);
}
source_debug_key = source_data->source.debug_key();
break;
}
case AttributionReport::Type::kAggregatableAttribution: {
@ -1323,6 +1325,7 @@ AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) {
if (!data.has_value()) {
corruptions.status_set.Put(ReportCorruptionStatus::kInvalidMetadata);
}
source_debug_key = source_data->source.debug_key();
break;
}
case AttributionReport::Type::kNullAggregatable:
@ -1351,7 +1354,8 @@ AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) {
*std::move(context_origin)),
report_id, report_time, initial_report_time,
std::move(external_report_id), failed_send_attempts,
*std::move(data), *std::move(reporting_origin));
*std::move(data), *std::move(reporting_origin),
source_debug_key);
}
std::vector<AttributionReport> AttributionStorageSql::GetAttributionReports(
@ -2524,8 +2528,7 @@ bool AttributionStorageSql::ClearReportsForSourceIds(
namespace {
bool AggregatableAttributionAllowedForBudgetLimit(
const AttributionReport::AggregatableAttributionData&
aggregatable_attribution,
const AttributionReport::AggregatableData& aggregatable_attribution,
int remaining_aggregatable_attribution_budget) {
if (remaining_aggregatable_attribution_budget <= 0) {
return false;
@ -2681,8 +2684,7 @@ AttributionStorageSql::MaybeStoreAggregatableAttributionReportData(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const auto* aggregatable_attribution =
absl::get_if<AttributionReport::AggregatableAttributionData>(
&report.data());
absl::get_if<AttributionReport::AggregatableData>(&report.data());
DCHECK(aggregatable_attribution);
if (num_aggregatable_attribution_reports >=

@ -542,7 +542,7 @@ AttributionReport ReportBuilder::Build() const {
/*initial_report_time=*/report_time_, external_report_id_,
/*failed_send_attempts=*/0,
AttributionReport::EventLevelData(trigger_data_, priority_, source_),
source_.common_info().reporting_origin());
source_.common_info().reporting_origin(), source_.debug_key());
}
AttributionReport ReportBuilder::BuildAggregatableAttribution() const {
@ -550,14 +550,14 @@ AttributionReport ReportBuilder::BuildAggregatableAttribution() const {
attribution_info_, report_id_, report_time_,
/*initial_report_time=*/report_time_, external_report_id_,
/*failed_send_attempts=*/0,
AttributionReport::AggregatableAttributionData(
AttributionReport::CommonAggregatableData(
aggregation_coordinator_origin_,
*attribution_reporting::AggregatableTriggerConfig::Create(
source_registration_time_config_, trigger_context_id_,
aggregatable_filtering_ids_max_bytes_)),
contributions_, source_),
source_.common_info().reporting_origin());
AttributionReport::AggregatableData(
aggregation_coordinator_origin_,
*attribution_reporting::AggregatableTriggerConfig::Create(
source_registration_time_config_, trigger_context_id_,
aggregatable_filtering_ids_max_bytes_),
source_.source_time(), contributions_,
source_.common_info().source_origin()),
source_.common_info().reporting_origin(), source_.debug_key());
}
AttributionReport ReportBuilder::BuildNullAggregatable() const {
@ -565,14 +565,15 @@ AttributionReport ReportBuilder::BuildNullAggregatable() const {
attribution_info_, report_id_, report_time_,
/*initial_report_time=*/report_time_, external_report_id_,
/*failed_send_attempts=*/0,
AttributionReport::NullAggregatableData(
AttributionReport::CommonAggregatableData(
aggregation_coordinator_origin_,
*attribution_reporting::AggregatableTriggerConfig::Create(
source_registration_time_config_, trigger_context_id_,
attribution_reporting::AggregatableFilteringIdsMaxBytes())),
source_.source_time()),
source_.common_info().reporting_origin());
AttributionReport::AggregatableData(
aggregation_coordinator_origin_,
*attribution_reporting::AggregatableTriggerConfig::Create(
source_registration_time_config_, trigger_context_id_,
attribution_reporting::AggregatableFilteringIdsMaxBytes()),
source_.source_time(),
/*contributions=*/{}, /*source_origin=*/std::nullopt),
source_.common_info().reporting_origin(),
/*source_debug_key=*/std::nullopt);
}
// Does not compare source IDs, as they are set by the underlying sqlite DB and
@ -598,30 +599,13 @@ bool operator==(const StoredSource& a, const StoredSource& b) {
// Does not compare the assembled report as it is returned by the
// aggregation service from all the other data.
bool operator==(const AttributionReport::CommonAggregatableData& a,
const AttributionReport::CommonAggregatableData& b) {
const auto tie = [](const AttributionReport::CommonAggregatableData& data) {
return std::make_tuple(data.aggregation_coordinator_origin,
data.aggregatable_trigger_config);
};
return tie(a) == tie(b);
}
bool operator==(const AttributionReport::AggregatableAttributionData& a,
const AttributionReport::AggregatableAttributionData& b) {
const auto tie =
[](const AttributionReport::AggregatableAttributionData& data) {
return std::make_tuple(data.common_data, data.contributions,
data.source_time, data.source_debug_key,
data.source_origin);
};
return tie(a) == tie(b);
}
bool operator==(const AttributionReport::NullAggregatableData& a,
const AttributionReport::NullAggregatableData& b) {
const auto tie = [](const AttributionReport::NullAggregatableData& data) {
return std::make_tuple(data.common_data, data.fake_source_time);
bool operator==(const AttributionReport::AggregatableData& a,
const AttributionReport::AggregatableData& b) {
const auto tie = [](const AttributionReport::AggregatableData& data) {
return std::make_tuple(data.aggregation_coordinator_origin(),
data.aggregatable_trigger_config(),
data.source_time(), data.contributions(),
data.source_origin());
};
return tie(a) == tie(b);
}
@ -630,11 +614,11 @@ bool operator==(const AttributionReport::NullAggregatableData& a,
// sqlite DB and should not be tested.
bool operator==(const AttributionReport& a, const AttributionReport& b) {
const auto tie = [](const AttributionReport& report) {
return std::make_tuple(report.attribution_info(), report.report_time(),
report.initial_report_time(),
report.external_report_id(),
report.failed_send_attempts(), report.data(),
report.reporting_origin());
return std::make_tuple(
report.attribution_info(), report.report_time(),
report.initial_report_time(), report.external_report_id(),
report.failed_send_attempts(), report.data(), report.reporting_origin(),
report.source_debug_key());
};
return tie(a) == tie(b);
}
@ -771,53 +755,35 @@ std::ostream& operator<<(std::ostream& out,
<< ",source_event_id=" << data.source_event_id
<< ",source_type=" << data.source_type << ",source_debug_key=";
if (data.source_debug_key.has_value()) {
out << *data.source_debug_key;
} else {
out << "null";
}
return out << ",randomized_response_rate=" << data.randomized_response_rate
<< ",attributed_truthfully=" << data.attributed_truthfully << "}";
}
std::ostream& operator<<(
std::ostream& out,
const AttributionReport::CommonAggregatableData& data) {
return out << "{aggregation_coordinator_origin="
<< (data.aggregation_coordinator_origin.has_value()
? data.aggregation_coordinator_origin->Serialize()
: "null")
<< ",aggregatable_trigger_config="
<< data.aggregatable_trigger_config << "}";
}
std::ostream& operator<<(
std::ostream& out,
const AttributionReport::AggregatableAttributionData& data) {
out << "{common_data=" << data.common_data << ",contributions=[";
std::ostream& operator<<(std::ostream& out,
const AttributionReport::AggregatableData& data) {
out << "{aggregation_coordinator_origin="
<< (data.aggregation_coordinator_origin().has_value()
? data.aggregation_coordinator_origin()->Serialize()
: "null")
<< ",aggregatable_trigger_config=" << data.aggregatable_trigger_config()
<< ",source_time=" << data.source_time() << ",contributions=[";
const char* separator = "";
for (const auto& contribution : data.contributions) {
for (const auto& contribution : data.contributions()) {
out << separator << contribution;
separator = ", ";
}
out << "],source_time=" << data.source_time << ",source_debug_key=";
out << "],source_origin=";
if (data.source_debug_key.has_value()) {
out << *data.source_debug_key;
if (data.source_origin().has_value()) {
out << *data.source_origin();
} else {
out << "null";
}
return out << ",source_origin=" << data.source_origin << "}";
}
std::ostream& operator<<(std::ostream& out,
const AttributionReport::NullAggregatableData& data) {
return out << "{common_data=" << data.common_data
<< ",fake_source_time=" << data.fake_source_time << "}";
return out << "}";
}
namespace {
@ -829,14 +795,22 @@ std::ostream& operator<<(std::ostream& out,
} // namespace
std::ostream& operator<<(std::ostream& out, const AttributionReport& report) {
return out << "{attribution_info=" << report.attribution_info()
<< ",id=" << *report.id()
<< ",report_time=" << report.report_time()
<< ",initial_report_time=" << report.initial_report_time()
<< ",external_report_id=" << report.external_report_id()
<< ",failed_send_attempts=" << report.failed_send_attempts()
<< ",data=" << report.data()
<< ",reporting_origin=" << report.reporting_origin() << "}";
out << "{attribution_info=" << report.attribution_info()
<< ",id=" << *report.id() << ",report_time=" << report.report_time()
<< ",initial_report_time=" << report.initial_report_time()
<< ",external_report_id=" << report.external_report_id()
<< ",failed_send_attempts=" << report.failed_send_attempts()
<< ",data=" << report.data()
<< ",reporting_origin=" << report.reporting_origin()
<< ",source_debug_key=";
if (report.source_debug_key().has_value()) {
out << *report.source_debug_key();
} else {
out << "null";
}
return out << "}";
}
std::ostream& operator<<(std::ostream& out, SendResult::Status status) {

@ -338,14 +338,8 @@ class ReportBuilder {
bool operator==(const StoredSource&, const StoredSource&);
bool operator==(const AttributionReport::CommonAggregatableData&,
const AttributionReport::CommonAggregatableData&);
bool operator==(const AttributionReport::AggregatableAttributionData&,
const AttributionReport::AggregatableAttributionData&);
bool operator==(const AttributionReport::NullAggregatableData&,
const AttributionReport::NullAggregatableData&);
bool operator==(const AttributionReport::AggregatableData&,
const AttributionReport::AggregatableData&);
bool operator==(const AttributionReport&, const AttributionReport&);
@ -371,14 +365,7 @@ std::ostream& operator<<(std::ostream& out,
const AttributionReport::EventLevelData& data);
std::ostream& operator<<(std::ostream& out,
const AttributionReport::CommonAggregatableData&);
std::ostream& operator<<(
std::ostream& out,
const AttributionReport::AggregatableAttributionData& data);
std::ostream& operator<<(std::ostream& out,
const AttributionReport::NullAggregatableData&);
const AttributionReport::AggregatableData& data);
std::ostream& operator<<(std::ostream& out, const AttributionReport& report);
@ -511,7 +498,7 @@ MATCHER_P(TriggerDebugKeyIs, matcher, "") {
}
MATCHER_P(ReportSourceDebugKeyIs, matcher, "") {
return ExplainMatchResult(matcher, arg.GetSourceDebugKey(), result_listener);
return ExplainMatchResult(matcher, arg.source_debug_key(), result_listener);
}
MATCHER_P(EventLevelDataIs, matcher, "") {
@ -542,36 +529,35 @@ MATCHER_P(ReportTypeIs, matcher, "") {
MATCHER_P(AggregatableAttributionDataIs, matcher, "") {
return ExplainMatchResult(
::testing::VariantWith<AttributionReport::AggregatableAttributionData>(
matcher),
::testing::VariantWith<AttributionReport::AggregatableData>(matcher),
arg.data(), result_listener);
}
MATCHER_P(NullAggregatableDataIs, matcher, "") {
return ExplainMatchResult(
::testing::VariantWith<AttributionReport::NullAggregatableData>(matcher),
::testing::VariantWith<AttributionReport::AggregatableData>(matcher),
arg.data(), result_listener);
}
MATCHER_P(AggregatableHistogramContributionsAre, matcher, "") {
return ExplainMatchResult(matcher, arg.contributions, result_listener);
return ExplainMatchResult(matcher, arg.contributions(), result_listener);
}
MATCHER_P(AggregationCoordinatorOriginIs, matcher, "") {
return ExplainMatchResult(
matcher, arg.common_data.aggregation_coordinator_origin, result_listener);
return ExplainMatchResult(matcher, arg.aggregation_coordinator_origin(),
result_listener);
}
MATCHER_P(SourceRegistrationTimeConfigIs, matcher, "") {
return ExplainMatchResult(matcher,
arg.common_data.aggregatable_trigger_config
.source_registration_time_config(),
result_listener);
return ExplainMatchResult(
matcher,
arg.aggregatable_trigger_config().source_registration_time_config(),
result_listener);
}
MATCHER_P(TriggerContextIdIs, matcher, "") {
return ExplainMatchResult(
matcher, arg.common_data.aggregatable_trigger_config.trigger_context_id(),
matcher, arg.aggregatable_trigger_config().trigger_context_id(),
result_listener);
}

@ -21,6 +21,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/types/optional_ref.h"
#include "components/attribution_reporting/aggregatable_filtering_id_max_bytes.h"
#include "components/attribution_reporting/aggregatable_trigger_config.h"
#include "components/attribution_reporting/aggregation_keys.h"
@ -88,19 +89,18 @@ void SerializeCommonAggregatableData(
trigger_config.aggregatable_filtering_id_max_bytes().value());
}
std::optional<AttributionReport::CommonAggregatableData>
DeserializeCommonAggregatableData(
const proto::AttributionCommonAggregatableMetadata& msg) {
std::optional<AttributionReport::AggregatableData> DeserializeAggregatableData(
const proto::AttributionCommonAggregatableMetadata& msg,
base::Time source_time,
base::optional_ref<const SuitableOrigin> source_origin) {
if (!msg.has_source_registration_time_config()) {
return std::nullopt;
}
std::optional<attribution_reporting::SuitableOrigin>
aggregation_coordinator_origin;
std::optional<SuitableOrigin> aggregation_coordinator_origin;
if (msg.has_coordinator_origin()) {
aggregation_coordinator_origin =
attribution_reporting::SuitableOrigin::Deserialize(
msg.coordinator_origin());
SuitableOrigin::Deserialize(msg.coordinator_origin());
if (!aggregation_coordinator_origin.has_value()) {
return std::nullopt;
}
@ -141,9 +141,10 @@ DeserializeCommonAggregatableData(
return std::nullopt;
}
return AttributionReport::CommonAggregatableData(
return AttributionReport::AggregatableData(
std::move(aggregation_coordinator_origin),
*std::move(aggregatable_trigger_config));
*std::move(aggregatable_trigger_config), source_time,
/*contributions=*/{}, source_origin.CopyAsOptional());
}
} // namespace
@ -180,7 +181,7 @@ void SetReadOnlySourceData(
}
std::string SerializeReadOnlySourceData(
const attribution_reporting::TriggerSpecs& trigger_specs,
const TriggerSpecs& trigger_specs,
double randomized_response_rate,
TriggerDataMatching trigger_data_matching,
bool cookie_based_debug_allowed,
@ -393,7 +394,7 @@ std::string SerializeAggregatableReportMetadata(
return msg.SerializeAsString();
}
std::optional<AttributionReport::AggregatableAttributionData>
std::optional<AttributionReport::AggregatableData>
DeserializeAggregatableReportMetadata(base::span<const uint8_t> blob,
const StoredSource& source) {
proto::AttributionAggregatableMetadata msg;
@ -402,9 +403,10 @@ DeserializeAggregatableReportMetadata(base::span<const uint8_t> blob,
return std::nullopt;
}
std::optional<AttributionReport::CommonAggregatableData> common_data =
DeserializeCommonAggregatableData(msg.common_data());
if (!common_data.has_value()) {
std::optional<AttributionReport::AggregatableData> data =
DeserializeAggregatableData(msg.common_data(), source.source_time(),
source.common_info().source_origin());
if (!data.has_value()) {
return std::nullopt;
}
@ -421,7 +423,7 @@ DeserializeAggregatableReportMetadata(base::span<const uint8_t> blob,
}
std::optional<uint64_t> filtering_id;
if (contribution_msg.has_filtering_id()) {
if (!common_data->aggregatable_trigger_config
if (!data->aggregatable_trigger_config()
.aggregatable_filtering_id_max_bytes()
.CanEncompass(contribution_msg.filtering_id())) {
return std::nullopt;
@ -434,8 +436,8 @@ DeserializeAggregatableReportMetadata(base::span<const uint8_t> blob,
base::checked_cast<int32_t>(contribution_msg.value()), filtering_id);
}
return AttributionReport::AggregatableAttributionData(
*std::move(common_data), std::move(contributions), source);
data->SetContributions(std::move(contributions));
return data;
}
std::string SerializeNullAggregatableReportMetadata(
@ -454,7 +456,7 @@ std::string SerializeNullAggregatableReportMetadata(
return msg.SerializeAsString();
}
std::optional<AttributionReport::NullAggregatableData>
std::optional<AttributionReport::AggregatableData>
DeserializeNullAggregatableReportMetadata(base::span<const uint8_t> blob) {
proto::AttributionNullAggregatableMetadata msg;
if (!msg.ParseFromArray(blob.data(), blob.size()) ||
@ -462,17 +464,11 @@ DeserializeNullAggregatableReportMetadata(base::span<const uint8_t> blob) {
return std::nullopt;
}
std::optional<AttributionReport::CommonAggregatableData> common_data =
DeserializeCommonAggregatableData(msg.common_data());
if (!common_data.has_value()) {
return std::nullopt;
}
base::Time fake_source_time = base::Time::FromDeltaSinceWindowsEpoch(
base::Microseconds(msg.fake_source_time()));
return AttributionReport::NullAggregatableData(
*std::move(common_data),
/*fake_source_time=*/
base::Time::FromDeltaSinceWindowsEpoch(
base::Microseconds(msg.fake_source_time())));
return DeserializeAggregatableData(msg.common_data(), fake_source_time,
/*source_origin=*/std::nullopt);
}
std::optional<TriggerSpecs> DeserializeTriggerSpecs(

@ -34,6 +34,10 @@ class SuitableOrigin;
class TriggerSpecs;
} // namespace attribution_reporting
namespace base {
class Time;
} // namespace base
namespace sql {
class Statement;
} // namespace sql
@ -109,11 +113,11 @@ std::optional<AttributionReport::EventLevelData>
DeserializeEventLevelReportMetadata(base::span<const uint8_t>,
const StoredSource&);
std::optional<AttributionReport::AggregatableAttributionData>
std::optional<AttributionReport::AggregatableData>
DeserializeAggregatableReportMetadata(base::span<const uint8_t>,
const StoredSource&);
std::optional<AttributionReport::NullAggregatableData>
std::optional<AttributionReport::AggregatableData>
DeserializeNullAggregatableReportMetadata(base::span<const uint8_t>);
std::string SerializeAttributionScopesData(