#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_H_
#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_H_
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/span.h"
#include "base/notreached.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "base/values.h"
#include "content/browser/aggregation_service/public_key.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/aggregation_service/aggregatable_report.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
class AggregatableReportRequest;
struct CONTENT_EXPORT AggregationServicePayloadContents {
enum class Operation {
kHistogram,
};
static constexpr size_t kMaximumFilteringIdMaxBytes = 8;
AggregationServicePayloadContents(
Operation operation,
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions,
std::optional<url::Origin> aggregation_coordinator_origin,
base::StrictNumeric<size_t> max_contributions_allowed,
size_t filtering_id_max_bytes);
AggregationServicePayloadContents(
const AggregationServicePayloadContents& other);
AggregationServicePayloadContents& operator=(
const AggregationServicePayloadContents& other);
AggregationServicePayloadContents(AggregationServicePayloadContents&& other);
AggregationServicePayloadContents& operator=(
AggregationServicePayloadContents&& other);
~AggregationServicePayloadContents();
Operation operation;
std::vector<blink::mojom::AggregatableReportHistogramContribution>
contributions;
std::optional<url::Origin> aggregation_coordinator_origin;
size_t max_contributions_allowed;
size_t filtering_id_max_bytes;
};
struct CONTENT_EXPORT AggregatableReportSharedInfo {
enum class DebugMode {
kDisabled,
kEnabled,
};
AggregatableReportSharedInfo(base::Time scheduled_report_time,
base::Uuid report_id,
url::Origin reporting_origin,
DebugMode debug_mode,
base::Value::Dict additional_fields,
std::string api_version,
std::string api_identifier);
AggregatableReportSharedInfo(const AggregatableReportSharedInfo& other) =
delete;
AggregatableReportSharedInfo& operator=(
const AggregatableReportSharedInfo& other) = delete;
AggregatableReportSharedInfo(AggregatableReportSharedInfo&& other);
AggregatableReportSharedInfo& operator=(AggregatableReportSharedInfo&& other);
~AggregatableReportSharedInfo();
AggregatableReportSharedInfo Clone() const;
std::string SerializeAsJson() const;
base::Time scheduled_report_time;
base::Uuid report_id;
url::Origin reporting_origin;
DebugMode debug_mode;
base::Value::Dict additional_fields;
std::string api_version;
std::string api_identifier;
};
class CONTENT_EXPORT AggregatableReport {
public:
struct CONTENT_EXPORT AggregationServicePayload {
AggregationServicePayload(
std::vector<uint8_t> payload,
std::string key_id,
std::optional<std::vector<uint8_t>> debug_cleartext_payload);
AggregationServicePayload(const AggregationServicePayload& other);
AggregationServicePayload& operator=(
const AggregationServicePayload& other);
AggregationServicePayload(AggregationServicePayload&& other);
AggregationServicePayload& operator=(AggregationServicePayload&& other);
~AggregationServicePayload();
std::vector<uint8_t> payload;
std::string key_id;
std::optional<std::vector<uint8_t>> debug_cleartext_payload;
};
class CONTENT_EXPORT Provider {
public:
virtual ~Provider();
virtual std::optional<AggregatableReport> CreateFromRequestAndPublicKey(
const AggregatableReportRequest& report_request,
PublicKey public_key) const;
static void SetDisableEncryptionForTestingTool(bool should_disable);
private:
static bool g_disable_encryption_for_testing_tool_;
};
static constexpr size_t kBucketDomainBitLength = 32;
static constexpr size_t kValueDomainBitLength = 64;
static constexpr std::string_view kDomainSeparationPrefix =
"aggregation_service";
AggregatableReport(std::optional<AggregationServicePayload> payload,
std::string shared_info,
std::optional<uint64_t> debug_key,
base::flat_map<std::string, std::string> additional_fields,
std::optional<url::Origin> aggregation_coordinator_origin);
AggregatableReport(const AggregatableReport& other);
AggregatableReport& operator=(const AggregatableReport& other);
AggregatableReport(AggregatableReport&& other);
AggregatableReport& operator=(AggregatableReport&& other);
~AggregatableReport();
const std::optional<AggregationServicePayload>& payload() const {
return payload_;
}
std::string_view shared_info() const { return shared_info_; }
std::optional<uint64_t> debug_key() const { return debug_key_; }
const base::flat_map<std::string, std::string>& additional_fields() const {
return additional_fields_;
}
const std::optional<url::Origin>& aggregation_coordinator_origin() const {
return aggregation_coordinator_origin_;
}
base::Value::Dict GetAsJson() const;
static std::optional<std::vector<uint8_t>> SerializePayloadForTesting(
const AggregationServicePayloadContents& payload_contents);
static std::optional<size_t> ComputePayloadLengthInBytesForTesting(
size_t num_contributions,
size_t filtering_id_max_bytes);
private:
std::optional<AggregationServicePayload> payload_;
std::string shared_info_;
std::optional<uint64_t> debug_key_;
base::flat_map<std::string, std::string> additional_fields_;
std::optional<url::Origin> aggregation_coordinator_origin_;
};
class CONTENT_EXPORT AggregatableReportRequest {
public:
enum class DelayType : uint8_t {
ScheduledWithReducedDelay = 0,
ScheduledWithFullDelay = 1,
Unscheduled = 2,
kMinValue = ScheduledWithReducedDelay,
kMaxValue = Unscheduled,
};
static constexpr std::string_view DelayTypeToString(DelayType delay_type) {
switch (delay_type) {
case DelayType::ScheduledWithReducedDelay:
return "ScheduledWithReducedDelay";
case DelayType::ScheduledWithFullDelay:
return "ScheduledWithFullDelay";
case DelayType::Unscheduled:
return "Unscheduled";
}
NOTREACHED();
}
static std::optional<AggregatableReportRequest> Create(
AggregationServicePayloadContents payload_contents,
AggregatableReportSharedInfo shared_info,
std::optional<AggregatableReportRequest::DelayType> delay_type =
std::nullopt,
std::string reporting_path = std::string(),
std::optional<uint64_t> debug_key = std::nullopt,
base::flat_map<std::string, std::string> additional_fields = {},
int failed_send_attempts = 0);
static std::optional<AggregatableReportRequest> CreateForTesting(
GURL processing_url,
AggregationServicePayloadContents payload_contents,
AggregatableReportSharedInfo shared_info,
std::optional<AggregatableReportRequest::DelayType> delay_type =
std::nullopt,
std::string reporting_path = std::string(),
std::optional<uint64_t> debug_key = std::nullopt,
base::flat_map<std::string, std::string> additional_fields = {},
int failed_send_attempts = 0);
static std::optional<AggregatableReportRequest> Deserialize(
base::span<const uint8_t> serialized_proto);
AggregatableReportRequest(AggregatableReportRequest&& other);
AggregatableReportRequest& operator=(AggregatableReportRequest&& other);
~AggregatableReportRequest();
const GURL& processing_url() const { return processing_url_; }
const AggregationServicePayloadContents& payload_contents() const {
return payload_contents_;
}
const AggregatableReportSharedInfo& shared_info() const {
return shared_info_;
}
std::string_view reporting_path() const { return reporting_path_; }
std::optional<uint64_t> debug_key() const { return debug_key_; }
const base::flat_map<std::string, std::string>& additional_fields() const {
return additional_fields_;
}
int failed_send_attempts() const { return failed_send_attempts_; }
std::optional<DelayType> delay_type() const { return delay_type_; }
GURL GetReportingUrl() const;
std::vector<uint8_t> Serialize() const;
private:
static std::optional<AggregatableReportRequest> CreateInternal(
GURL processing_url,
AggregationServicePayloadContents payload_contents,
AggregatableReportSharedInfo shared_info,
std::optional<AggregatableReportRequest::DelayType> delay_type,
std::string reporting_path,
std::optional<uint64_t> debug_key,
base::flat_map<std::string, std::string> additional_fields,
int failed_send_attempts);
AggregatableReportRequest(
GURL processing_url,
AggregationServicePayloadContents payload_contents,
AggregatableReportSharedInfo shared_info,
std::optional<AggregatableReportRequest::DelayType> delay_type,
std::string reporting_path,
std::optional<uint64_t> debug_key,
base::flat_map<std::string, std::string> additional_fields,
int failed_send_attempts);
GURL processing_url_;
AggregationServicePayloadContents payload_contents_;
AggregatableReportSharedInfo shared_info_;
std::string reporting_path_;
std::optional<uint64_t> debug_key_;
base::flat_map<std::string, std::string> additional_fields_;
int failed_send_attempts_ = 0;
std::optional<AggregatableReportRequest::DelayType> delay_type_;
};
CONTENT_EXPORT GURL GetAggregationServiceProcessingUrl(const url::Origin&);
CONTENT_EXPORT std::vector<uint8_t> EncryptAggregatableReportPayloadWithHpke(
base::span<const uint8_t> report_payload_plaintext,
base::span<const uint8_t> public_key,
base::span<const uint8_t> report_authenticated_info);
}
#endif