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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
content / browser / aggregation_service / aggregatable_report_assembler.h [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_ASSEMBLER_H_
#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_ASSEMBLER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "content/browser/aggregation_service/aggregatable_report.h"
#include "content/browser/aggregation_service/aggregation_service_key_fetcher.h"
#include "content/browser/aggregation_service/public_key.h"
#include "content/common/content_export.h"
template <class T>
class scoped_refptr;
namespace network {
class SharedURLLoaderFactory;
} // namespace network
namespace content {
class AggregationServiceStorageContext;
class StoragePartition;
// This class provides an interface for assembling an aggregatable report. It is
// therefore responsible for taking a request, identifying and requesting the
// appropriate public keys, and generating and returning the AggregatableReport.
class CONTENT_EXPORT AggregatableReportAssembler {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class AssemblyStatus {
kOk = 0,
// The attempt to fetch a public key failed.
kPublicKeyFetchFailed = 1,
// An internal error occurred while attempting to construct the report.
kAssemblyFailed = 2,
// The limit on the number of simultenous requests has been reached.
kTooManySimultaneousRequests = 3,
kMaxValue = kTooManySimultaneousRequests,
};
using AssemblyCallback =
base::OnceCallback<void(AggregatableReportRequest,
std::optional<AggregatableReport>,
AssemblyStatus)>;
// While we shouldn't hit these limits in typical usage, we protect against
// the possibility of unbounded memory growth
static constexpr size_t kMaxSimultaneousRequests = 1000;
AggregatableReportAssembler(AggregationServiceStorageContext* storage_context,
StoragePartition* storage_partition);
// Not copyable or movable.
AggregatableReportAssembler(const AggregatableReportAssembler& other) =
delete;
AggregatableReportAssembler& operator=(
const AggregatableReportAssembler& other) = delete;
virtual ~AggregatableReportAssembler();
static std::unique_ptr<AggregatableReportAssembler> CreateForTesting(
std::unique_ptr<AggregationServiceKeyFetcher> fetcher,
std::unique_ptr<AggregatableReport::Provider> report_provider);
// Used by the aggregation service tool to inject a `url_loader_factory` to
// AggregationServiceNetworkFetcherImpl if one is provided.
static std::unique_ptr<AggregatableReportAssembler> CreateForTesting(
AggregationServiceStorageContext* storage_context,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
bool enable_debug_logging);
// Fetches the necessary public keys and uses it to construct an
// AggregatableReport from the information in `report_request`. See the
// AggregatableReport documentation for more detail on the returned report.
virtual void AssembleReport(AggregatableReportRequest report_request,
AssemblyCallback callback);
protected:
// For testing only.
AggregatableReportAssembler(
AggregationServiceStorageContext* storage_context,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
bool enable_debug_logging = false);
private:
// Represents a request to assemble a report that has not completed.
struct PendingRequest {
PendingRequest(AggregatableReportRequest report_request,
AssemblyCallback callback,
size_t num_processing_urls);
// Move-only.
PendingRequest(PendingRequest&& other);
PendingRequest& operator=(PendingRequest&& other);
~PendingRequest();
AggregatableReportRequest report_request;
AssemblyCallback callback;
// How many key fetches for this request have returned, including errors.
size_t num_returned_key_fetches = 0;
// The PublicKey returned for each key fetch request. Indices correspond to
// the ordering of `report_request.processing_urls`. Each element is
// `std::nullopt` if that key fetch either has not yet returned or has
// returned an error.
std::vector<std::optional<PublicKey>> processing_url_keys;
};
AggregatableReportAssembler(
std::unique_ptr<AggregationServiceKeyFetcher> fetcher,
std::unique_ptr<AggregatableReport::Provider> report_provider);
// Called when a result is returned from the key fetcher. Handles throwing
// errors on a failed fetch, waiting for both results to return and calling
// into `OnAllPublicKeysFetched()` when appropriate. `processing_url_index` is
// an index into the corresponding AggregatableReportRequest's
// `processing_urls` vector, indicating which URL this fetch is for.
void OnPublicKeyFetched(
int64_t report_id,
size_t processing_url_index,
std::optional<PublicKey> key,
AggregationServiceKeyFetcher::PublicKeyFetchStatus status);
// Call when all results have been returned from the key fetcher. Handles
// calling into `AssembleReportUsingKeys()` when appropriate and returning
// any assembled report or throwing an error if assembly fails.
void OnAllPublicKeysFetched(int64_t report_id,
PendingRequest& pending_request);
// Keyed by a token for easier lookup.
base::flat_map<int64_t, PendingRequest> pending_requests_;
// Used to generate unique ids for PendingRequests. These need to be unique
// per Assembler for tracking pending requests.
int64_t unique_id_counter_ = 0;
std::unique_ptr<AggregationServiceKeyFetcher> fetcher_;
std::unique_ptr<AggregatableReport::Provider> report_provider_;
};
} // namespace content
#endif // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_ASSEMBLER_H_