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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
content / browser / interest_group / ad_auction_service_impl.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_INTEREST_GROUP_AD_AUCTION_SERVICE_IMPL_H_
#define CONTENT_BROWSER_INTEREST_GROUP_AD_AUCTION_SERVICE_IMPL_H_
#include <map>
#include <memory>
#include <set>
#include <vector>
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/uuid.h"
#include "content/browser/fenced_frame/fenced_frame_url_mapping.h"
#include "content/browser/interest_group/auction_nonce_manager.h"
#include "content/browser/interest_group/auction_runner.h"
#include "content/browser/interest_group/auction_worklet_manager.h"
#include "content/browser/interest_group/bidding_and_auction_serializer.h"
#include "content/browser/interest_group/interest_group_auction_reporter.h"
#include "content/common/content_export.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/document_service.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom-forward.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/client_security_state.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/common/interest_group/auction_config.h"
#include "third_party/blink/public/mojom/interest_group/ad_auction_service.mojom.h"
#include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-forward.h"
#include "third_party/blink/public/mojom/parakeet/ad_request.mojom.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-forward.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
class InterestGroupManagerImpl;
class PrivateAggregationManager;
class ReconnectableURLLoaderFactory;
class RenderFrameHost;
class RenderFrameHostImpl;
struct BiddingAndAuctionServerKey;
// Implements the AdAuctionService service called by Blink code.
class CONTENT_EXPORT AdAuctionServiceImpl final
: public DocumentService<blink::mojom::AdAuctionService>,
public AuctionWorkletManager::Delegate {
public:
// Factory method for creating an instance of this interface that is
// bound to the lifetime of the frame or receiver (whichever is shorter).
static void CreateMojoService(
RenderFrameHost* render_frame_host,
mojo::PendingReceiver<blink::mojom::AdAuctionService> receiver);
// blink::mojom::AdAuctionService.
void JoinInterestGroup(const blink::InterestGroup& group,
JoinInterestGroupCallback callback) override;
void LeaveInterestGroup(const url::Origin& owner,
const std::string& name,
LeaveInterestGroupCallback callback) override;
void LeaveInterestGroupForDocument() override;
void ClearOriginJoinedInterestGroups(
const url::Origin& owner,
const std::vector<std::string>& interest_groups_to_keep,
ClearOriginJoinedInterestGroupsCallback callback) override;
void UpdateAdInterestGroups() override;
void RunAdAuction(
const blink::AuctionConfig& config,
mojo::PendingReceiver<blink::mojom::AbortableAdAuction> abort_receiver,
RunAdAuctionCallback callback) override;
void DeprecatedGetURLFromURN(
const GURL& urn_url,
bool send_reports,
DeprecatedGetURLFromURNCallback callback) override;
void DeprecatedReplaceInURN(
const GURL& urn_url,
const std::vector<blink::AuctionConfig::AdKeywordReplacement>&
replacements,
DeprecatedReplaceInURNCallback callback) override;
void GetInterestGroupAdAuctionData(
const url::Origin& seller,
const std::optional<url::Origin>& coordinator,
blink::mojom::AuctionDataConfigPtr config,
GetInterestGroupAdAuctionDataCallback callback) override;
void CreateAdRequest(blink::mojom::AdRequestConfigPtr config,
CreateAdRequestCallback callback) override;
void FinalizeAd(const std::string& ads_guid,
const blink::AuctionConfig& config,
FinalizeAdCallback callback) override;
scoped_refptr<network::SharedURLLoaderFactory>
GetRefCountedTrustedURLLoaderFactory();
// AuctionWorkletManager::Delegate implementation:
network::mojom::URLLoaderFactory* GetFrameURLLoaderFactory() override;
network::mojom::URLLoaderFactory* GetTrustedURLLoaderFactory() override;
void PreconnectSocket(
const GURL& url,
const net::NetworkAnonymizationKey& network_anonymization_key) override;
RenderFrameHostImpl* GetFrame() override;
scoped_refptr<SiteInstance> GetFrameSiteInstance() override;
network::mojom::ClientSecurityStatePtr GetClientSecurityState() override;
std::optional<std::string> GetCookieDeprecationLabel() override;
void GetBiddingAndAuctionServerKey(
const std::optional<url::Origin>& coordinator,
base::OnceCallback<void(base::expected<BiddingAndAuctionServerKey,
std::string>)> callback) override;
using DocumentService::origin;
using DocumentService::render_frame_host;
private:
using ReporterList = std::list<std::unique_ptr<InterestGroupAuctionReporter>>;
class BiddingAndAuctionDataConstructionState {
public:
BiddingAndAuctionDataConstructionState();
BiddingAndAuctionDataConstructionState(
BiddingAndAuctionDataConstructionState&& other);
~BiddingAndAuctionDataConstructionState();
base::TimeTicks start_time; // time used for metrics
std::unique_ptr<BiddingAndAuctionServerKey> key;
std::unique_ptr<BiddingAndAuctionData> data;
base::Uuid request_id;
url::Origin seller;
std::optional<url::Origin> coordinator;
base::Time timestamp; // timestamp to include in the request.
blink::mojom::AuctionDataConfigPtr config;
GetInterestGroupAdAuctionDataCallback callback;
};
// `render_frame_host` must not be null, and DocumentService guarantees
// `this` will not outlive the `render_frame_host`.
AdAuctionServiceImpl(
RenderFrameHost& render_frame_host,
mojo::PendingReceiver<blink::mojom::AdAuctionService> receiver);
// `this` can only be destroyed by DocumentService.
~AdAuctionServiceImpl() override;
// Checks if a join or leave interest group is allowed to be sent from the
// current renderer. If not, returns false and invokes
// ReportBadMessageAndDeleteThis().
bool JoinOrLeaveApiAllowedFromRenderer(const url::Origin& owner,
const char* invoked_method);
// Checks if `feature` is enabled for the frame, and returns true if so, and
// false if not. Additionally, if the feature is enabled, prints a warning to
// the console if the feature would not be enabled if the default state of the
// feature across cross-origin frames were switched to disabled instead of
// enabled.
bool IsPermissionPolicyEnabledAndWarnIfNeeded(
blink::mojom::PermissionsPolicyFeature feature,
const char* method);
// Returns true if `origin` is allowed to perform the specified
// `interest_group_api_operation` in this frame. Must be called on worklet /
// interest group origins before using them in any interest group API.
bool IsInterestGroupAPIAllowed(ContentBrowserClient::InterestGroupApiOperation
interest_group_api_operation,
const url::Origin& origin) const;
// Deletes `auction`.
void OnAuctionComplete(
RunAdAuctionCallback callback,
GURL urn_uuid,
AuctionRunner* auction,
bool aborted_by_script,
std::optional<blink::InterestGroupKey> winning_group_key,
std::optional<blink::AdSize> requested_ad_size,
std::optional<blink::AdDescriptor> ad_descriptor,
std::vector<blink::AdDescriptor> ad_component_descriptors,
std::vector<std::string> errors,
std::unique_ptr<InterestGroupAuctionReporter> reporter,
bool contained_server_auction,
bool contained_on_device_auction,
AuctionResult result);
void OnReporterComplete(ReporterList::iterator reporter_it);
void MaybeLogPrivateAggregationFeatures(
const std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>&
private_aggregation_requests);
// On failing to fetch ad auction data, call the first callback in
// ba_data_callbacks_ & start loading the next following request in
// ba_data_callbacks_.
void ReturnEmptyGetInterestGroupAdAuctionDataCallback(const std::string& msg);
void LoadAuctionDataAndKeyForNextQueuedRequest();
void OnGotAuctionData(base::Uuid request_id, BiddingAndAuctionData data);
void OnGotBiddingAndAuctionServerKey(
base::Uuid request_id,
base::expected<BiddingAndAuctionServerKey, std::string> maybe_key);
void OnGotAuctionDataAndKey(base::Uuid request_id);
InterestGroupManagerImpl& GetInterestGroupManager() const;
url::Origin GetTopWindowOrigin() const;
void CreateUnderlyingTrustedURLLoaderFactory(
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory);
AdAuctionPageData* GetAdAuctionPageData();
// For each buyer in `config`, preconnect to its origin and bidding signals
// origin if the origins have been cached from previous interest group joins
// or auctions. This function needs to be called separately to preconnect to
// origins for `config`'s component auctions. Returns the number of buyers
// that were preconnected.
size_t PreconnectToBuyerOrigins(const blink::AuctionConfig& config);
// To avoid race conditions associated with top frame navigations (mentioned
// in document_service.h), we need to save the values of the main frame
// URL and origin in the constructor.
const url::Origin main_frame_origin_;
const GURL main_frame_url_;
mojo::Remote<network::mojom::URLLoaderFactory> frame_url_loader_factory_;
// A URLLoaderFactory connecting to the underlying factory created by
// CreateUnderlyingTrustedURLLoaderFactory(), with reconnecting support. This
// can be used for reporting requests, which might happen after the frame is
// destroyed.
scoped_refptr<ReconnectableURLLoaderFactory>
ref_counted_trusted_url_loader_factory_;
// Used to create AuctionMetricsRecorders, which store data needed to record
// UKM. This must be before `auction_worklet_manager_`, since worklet owners
// may keep references to the AuctionMetricsRecorders owned by the
// `auction_metrics_recorder_manager_`.
AuctionMetricsRecorderManager auction_metrics_recorder_manager_;
// This must be before `auctions_`, since auctions may own references to
// worklets it manages.
AuctionWorkletManager auction_worklet_manager_;
// Manages auction nonces issued by prior calls to CreateAuctionNonce,
// which are used by subsequent calls to RunAdAuction.
AuctionNonceManager auction_nonce_manager_;
// Use a map instead of a list so can remove entries without destroying them.
// TODO(mmenke): Switch to std::set() and use extract() once that's allowed.
std::map<AuctionRunner*, std::unique_ptr<AuctionRunner>> auctions_;
ReporterList reporters_;
// Safe to keep as it will outlive the associated `RenderFrameHost` and
// therefore `this`, being tied to the lifetime of the `StoragePartition`.
const raw_ptr<PrivateAggregationManager> private_aggregation_manager_;
// Whether a UseCounter has already been logged for usage of the Private
// Aggregation API in general, the extended Private Aggregation API and the
// Private Aggregation API's enableDebugMode(), respectively.
bool has_logged_private_aggregation_web_features_ = false;
bool has_logged_extended_private_aggregation_web_feature_ = false;
bool has_logged_private_aggregation_enable_debug_mode_web_feature_ = false;
bool has_logged_private_aggregation_filtering_id_web_feature_ = false;
// Track the state of GetInterestGroupAdAuctionData calls. One request will be
// handled at a time (the first in the queue). The first
// BiddingAndAuctionDataConstructionState's data and key will be edited in
// place as they are loaded.
base::queue<BiddingAndAuctionDataConstructionState> ba_data_callbacks_;
// True if a feature is currently enabled, but would be disabled if the
// default policy for the feature were switched to EnableForSelf. Lazily
// populated.
std::map<blink::mojom::PermissionsPolicyFeature, bool>
should_warn_about_feature_;
base::WeakPtrFactory<AdAuctionServiceImpl> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_INTEREST_GROUP_AD_AUCTION_SERVICE_IMPL_H_