1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/attribution_reporting/aggregatable_utils.h"
#include <optional>
#include <vector>
#include "base/check.h"
#include "base/functional/function_ref.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "components/attribution_reporting/aggregatable_trigger_config.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/source_registration_time_config.mojom.h"
namespace attribution_reporting {
namespace {
std::vector<NullAggregatableReport> GetNullAggregatableReportsForLookback(
base::Time trigger_time,
std::optional<base::Time> attributed_source_time,
int days_lookback,
GenerateNullAggregatableReportFunc generate_func) {
std::vector<NullAggregatableReport> reports;
for (int i = 0; i <= days_lookback; i++) {
base::Time fake_source_time = trigger_time - base::Days(i);
if (attributed_source_time &&
RoundDownToWholeDaySinceUnixEpoch(fake_source_time) ==
*attributed_source_time) {
continue;
}
if (generate_func(i)) {
reports.emplace_back(fake_source_time);
}
}
return reports;
}
} // namespace
base::Time RoundDownToWholeDaySinceUnixEpoch(base::Time time) {
return base::Time::UnixEpoch() +
(time - base::Time::UnixEpoch()).FloorToMultiple(base::Days(1));
}
std::vector<NullAggregatableReport> GetNullAggregatableReports(
const AggregatableTriggerConfig& config,
base::Time trigger_time,
std::optional<base::Time> attributed_source_time,
GenerateNullAggregatableReportFunc generate_func) {
// See spec
// https://wicg.github.io/attribution-reporting-api/#generate-null-attribution-reports.
mojom::SourceRegistrationTimeConfig source_registration_time_config =
config.source_registration_time_config();
static_assert((attribution_reporting::kMaxSourceExpiry.InDays() + 1) *
kNullReportsRateIncludeSourceRegistrationTime >
kNullReportsRateExcludeSourceRegistrationTime);
base::UmaHistogramEnumeration("Conversions.SourceRegistrationTimeConfig",
source_registration_time_config);
switch (source_registration_time_config) {
case mojom::SourceRegistrationTimeConfig::kInclude: {
std::optional<base::Time> rounded_attributed_source_time;
if (attributed_source_time) {
rounded_attributed_source_time =
RoundDownToWholeDaySinceUnixEpoch(*attributed_source_time);
}
CHECK(!config.ShouldCauseAReportToBeSentUnconditionally());
return GetNullAggregatableReportsForLookback(
trigger_time, rounded_attributed_source_time,
/*days_lookback=*/
kMaxSourceExpiry.InDays(), generate_func);
}
case mojom::SourceRegistrationTimeConfig::kExclude: {
const bool has_real_report = attributed_source_time.has_value();
if (has_real_report) {
return {};
}
if (config.ShouldCauseAReportToBeSentUnconditionally()) {
return {
NullAggregatableReport{
.fake_source_time = trigger_time,
},
};
}
return GetNullAggregatableReportsForLookback(
trigger_time, attributed_source_time, /*days_lookback=*/0,
generate_func);
}
}
}
bool IsAggregatableValueInRange(int value) {
return value > 0 && value <= kMaxAggregatableValue;
}
bool IsAggregatableBudgetInRange(int budget) {
return budget >= 0 && budget <= kMaxAggregatableValue;
}
} // namespace attribution_reporting
|