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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
content / services / auction_worklet / public / mojom / seller_worklet.mojom [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.
module auction_worklet.mojom;
import "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom";
import "content/services/auction_worklet/public/mojom/real_time_reporting.mojom";
import "content/services/auction_worklet/public/mojom/reject_reason.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "third_party/blink/public/mojom/devtools/devtools_agent.mojom";
import "third_party/blink/public/mojom/interest_group/ad_display_size.mojom";
import "third_party/blink/public/mojom/interest_group/interest_group_types.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
// The other seller associated with a bid. For component (nested)
// SellerWorklets, `top_level_seller` is the seller for the parent auction.
// For top-level SellerWorklets, `component_seller` is the seller in the
// nested component auction where the bid was originally made.
union ComponentAuctionOtherSeller {
url.mojom.Origin top_level_seller;
url.mojom.Origin component_seller;
};
// When ScoreAd() is invoked for a component seller worklet, it returns an
// additional set of parameters that are passed to the top-level seller
// worklet in place of output from the GenerateBid() call that created the bid.
struct ComponentAuctionModifiedBidParams {
// Ad metadata to send to the top-level seller in place of
// BidderWorkletBid::ad.
string ad;
// Bid value and currency to send to the top-level seller seller in place of
// BidderWorkletBid::bid.
double? bid;
blink.mojom.AdCurrency? bid_currency;
};
// Input parameters specific to a component auction's ReportResult() method.
struct ComponentAuctionReportResultParams {
// Metadata returned by the top-level seller's ReportResult() method, as JSON.
string top_level_seller_signals;
// The stochastically rounded numeric value of the bid returned by the
// component seller's ScoreAd() method. May be the same value as the original
// bid.
double? modified_bid;
};
// Represents the time between SellerWorklet::ScoreAd and each of the
// dependencies to SellerWorklet::ScoreAdIfReady, which can help to identify
// the slowest dependency, both in absolute terms and relative to other
// dependencies. Each of the latencies recorded here may be null if that
// dependency didn't apply for this call to ScoreAd.
struct ScoreAdDependencyLatencies {
// Load of Script
mojo_base.mojom.TimeDelta? code_ready_latency;
// Download of DirectFromSellerSignals
mojo_base.mojom.TimeDelta? direct_from_seller_signals_latency;
// Download of TrustedScoringSignals
mojo_base.mojom.TimeDelta? trusted_scoring_signals_latency;
// Times of each step of the ScoreAd flow, used to compute start and end
// times for latency phase UKMs.
mojo_base.mojom.TimeTicks deps_wait_start_time;
mojo_base.mojom.TimeTicks score_ad_start_time;
mojo_base.mojom.TimeTicks score_ad_finish_time;
};
// How long particular tasks took. Unlike ScoreAdDependencyLatencies this
// doesn't denote how long things blocked for --- e.g. the fetch times are
// how long the download took, even for later calls to scoreAd() that may not
// actually wait for the download since it's already in memory.
struct SellerTimingMetrics {
mojo_base.mojom.TimeDelta? js_fetch_latency;
// How long it took to execute the script (including both the top-level
// and the function).
mojo_base.mojom.TimeDelta script_latency;
bool script_timed_out;
};
// Interface for returning ScoreAd results. The advantage of having an interface
// is that it makes ScoreAd() calls cancellable, and allows callbacks passed
// over the Mojo pipe to be deleted when the Mojo pipe is, to avoid setting off
// the raw pointer lifetime validation logic.
interface ScoreAdClient {
// Called when a ScoreAd() invocation completes.
//
// Parameters:
// `score` Non-negative score the SellerWorklet assigns to the bid. A value
// of 0 indicates either an error running the script, or that the script
// indicated the bid should not be used.
//
// `bid_in_seller_currency` If present, denotes the conversion of bidder's
// bid to seller's currency. Should be present only when auction
// configuration specifies what the seller currency is.
//
// `reject_reason` The reason this bid was rejected by the auction (i.e., the
// reason why `score` was non-positive). Default to kNotAvailable if not set.
// Will be ignored if `score` is positive.
//
// `component_auction_modified_bid_params` If this is a component seller
// worklet, contains parameters to pass to the top-level seller worklet
// in place of values from the original bidder worklet's BidderWorkletBid.
//
// `scoring_signals_data_version` The value of the Data-Version header served
// with the trusted scoring signals. nullopt when the header wasn't present.
//
// `debug_loss_report_url` The URL to request if this bid does not win the
// auction. It's requested if the auction runs to completion and this is not
// the winning bid, including the case that this worklet rejects this bid
// outright, giving it a score <= 0. This field has the debug prefix because
// it's part of an interim reporting API that will be replaced with
// standardized reporting APIs once available. It must be a valid HTTPS URL.
//
// `debug_win_report_url` The URL to request if this bid wins the auction.
// This field has the debug prefix because it's part of an interim reporting
// API that will be replaced with standardized reporting APIs once available.
// It must be a valid HTTPS URL.
//
// `pa_requests` The various requests made to the Private Aggregation API.
//
// `real_time_contributions` Real time reporting contributions.
//
// `score_ad_timing_metrics` Time metrics relevant to this call.
//
// `score_ad_dependency_latencies` How long various depedent-on operations
// were waited for on this particular call.
//
// `errors` are various error messages to be used for debugging. These are too
// sensitive for the renderers to see. `errors` should not be assumed to be
// empty if `score` is positive, nor should it be assumed to be non-empty if
// `score` is 0.
OnScoreAdComplete(double score,
RejectReason reject_reason,
ComponentAuctionModifiedBidParams?
component_auction_modified_bid_params,
double? bid_in_seller_currency,
uint32? scoring_signals_data_version,
url.mojom.Url? debug_loss_report_url,
url.mojom.Url? debug_win_report_url,
array<PrivateAggregationRequest> pa_requests,
array<RealTimeReportingContribution> real_time_contributions,
SellerTimingMetrics score_ad_timing_metrics,
ScoreAdDependencyLatencies score_ad_dependency_latencies,
array<string> errors);
};
// Manages the auction workflow for one loaded FLEDGE seller worklet.
// See https://github.com/WICG/turtledove/blob/main/FLEDGE.md
//
// The SellerWorklet is functionally stateless, so methods are idempotent
// and can be called multiple times, in any order, for multiple auctions
// using the same worklet. There is no need to wait for one callback to be
// invoked before calling another method. There is no guarantee methods will
// complete in the order they are invoked.
interface SellerWorklet {
// Calls the Javascript scoreAd() function to evaluate a bid. No data is
// leaked between consecutive invocations of this method, or between
// invocations of this method and ReportResult().
//
// In the case a worklet needs to fetch trusted scoring signals before
// running any Javascript, the method may wait so it can merge several signals
// fetched together. See SendPendingSignalsRequests() for more information.
//
// Arguments:
// `ad_metadata_json` JSON representation of the `ad` value returned by the
// BidderWorklet that offered the bid.
//
// `bid` The numeric value of the bid offered by the BidderWorklet.
//
// `bid_currency` Currency of the bid offered by the BidderWorklet.
//
// `auction_ad_config_non_shared_params` Values in an AuctionConfig that can
// vary between auctions that can share a SellerWorklet.
//
// `direct_from_seller_seller_signals` The subresource URL of the
// DirectFromSellerSignals for the seller, as produced by concatenating the
// `directFromSellerSignals` URL prefix field passed from runAdAuction() with
// "?sellerSignals". Since this is fetched from a subresource bundle, it may
// only be fetched using the URLLoaderFactory passed in when creating the
// worklet.
//
// `direct_from_seller_seller_signals_header_ad_slot` A JSON string of the
// DirectFromSellerSignals for the seller. Must not be passed if
// `direct_from_seller_seller_signals` or
// `direct_from_seller_auction_signals` is passed.
//
// `direct_from_seller_auction_signals` The subresource URL of the
// directFromSellerSignals for the seller and all buyers, as produced by
// concatenating the `directFromSellerSignals` URL prefix field passed from
// runAdAuction() with "?auctionSignals". Since this is fetched from a
// subresource bundle, it may only be fetched using the URLLoaderFactory
// passed in when creating the worklet.
//
// `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the
// DirectFromSellerSignals for the seller and all buyers. Must not be passed
// if `direct_from_seller_auction_signals` or
// `direct_from_seller_seller_signals` is passed.
//
// `browser_signals_other_seller` The origin of the other seller associated
// with the bid. If this is a component seller worklet, it's the
// top-level seller. If this is a top-level seller scoring a bid from a
// component auction, it's the seller in the component auction.
// Null if this is the top-level seller scoring its own bids.
//
// `component_expect_bid_currency` If this is a component auction, specifies
// what currency the top-level auction expects it to provide, if any.
// nullopt for top-level auction.
//
// `browser_signal_interest_group_owner` The owner of the interest group
// that offered the bid.
//
// `browser_signal_render_url` The `renderUrl` returned by the
// BidderWorklet making the bid.
//
// `browser_signal_selected_buyer_and_seller_reporting_id`
// The selected reporting id from the interest group's ad's
// `selectableBuyerAndSellerReportingIds` array.
//
// `browser_signal_buyer_and_seller_reporting_id` This is the reporting id
// from from the interest group's ad's buyerAndSellerReportingId field,
// which is provided to both buyer and seller reporting worklets
// (reportWin() and reportResult() respectively). This is only provided to
// scoreAd() if browser_signal_selected_buyer_and_seller_reporting_id is
// also present.
//
// `browser_signal_ad_component_urls` The `adComponents` array returned by
// the BidderWorklet making the bid.
//
// `browser_signal_bidding_duration_msecs` is the duration the BiddingWorklet
// took to generate the bid. Taken as milliseconds to reduce granularity of
// timing information passed to an untrusted process.
//
// `browser_signal_render_size` is the size associated with the `renderUrl`
// returned by the BidderWorklet making the bid. This argument is optional.
// When there is no size associated with the `renderUrl`, it will be a
// nullopt.
// See explainer: https://github.com/WICG/turtledove/blob/main/FLEDGE.md#32-on-device-bidding
//
// `browser_signal_for_debugging_only_in_cooldown_or_lockout` Whether the
// browser is under lockout or the seller's origin is under cooldown for
// sending forDebuggingOnly reports.
//
// `seller_timeout` Restrict the runtime of the seller's scoring script. Any
// timeout higher than 500 ms will be clamped to 500 ms before passing in as
// `seller_timeout`. Null if not provided by the publisher page. Null will be
// passed to the worklet in that case.
//
// `trace_id` ID of a nestable asynchronous trace event of category `fledge`
// to use with tracing calls.
//
// `score_ad_client` When the ScoreAd completes, successfully or not, its
// OnScoreAdComplete() method will be invoked with the results.
ScoreAd(string ad_metadata_json,
double bid,
blink.mojom.AdCurrency? bid_currency,
blink.mojom.AuctionAdConfigNonSharedParams
auction_ad_config_non_shared_params,
url.mojom.Url? direct_from_seller_seller_signals,
string? direct_from_seller_seller_signals_header_ad_slot,
url.mojom.Url? direct_from_seller_auction_signals,
string? direct_from_seller_auction_signals_header_ad_slot,
ComponentAuctionOtherSeller? browser_signals_other_seller,
blink.mojom.AdCurrency? component_expect_bid_currency,
url.mojom.Origin browser_signal_interest_group_owner,
url.mojom.Url browser_signal_render_url,
string? browser_signal_selected_buyer_and_seller_reporting_id,
string? browser_signal_buyer_and_seller_reporting_id,
array<url.mojom.Url> browser_signal_ad_component_render_urls,
uint32 browser_signal_bidding_duration_msecs,
blink.mojom.AdSize? browser_signal_render_size,
bool browser_signal_for_debugging_only_in_cooldown_or_lockout,
mojo_base.mojom.TimeDelta? seller_timeout,
uint64 trace_id,
url.mojom.Origin bidder_joining_origin,
pending_remote<ScoreAdClient> score_ad_client);
// Hint to the worklet to send a network request for any needed trusted
// signals data now. SellerWorklets normally wait briefy for there to be a
// number of ScoreAd() calls before requesting trusted scoring signals so the
// request can be batched together. This method can be called once all bids
// have been generated to minimize the amount of time an auction spends
// waiting on trusted signals data once the final bid has been generated. Does
// nothing if no trusted scoring signals need to be fetched.
SendPendingSignalsRequests();
// Calls the Javascript reportResult() function to get the information needed
// to report the result of the auction to the seller. May only be called once
// ScoreAd() has successfully scored an ad, which will ensure the worklet has
// completed loading. It does not make sense to invoke this with a score not
// generated by a previous ScoreAd() call, so this should not limit consumers.
// No data is leaked between consecutive invocations of this method, or
// between invocations of this method and ScoreAd().
//
// Arguments:
// `auction_ad_config_non_shared_params` Values in an AuctionConfig that can
// vary between auctions that can share a SellerWorklet.
//
// `direct_from_seller_seller_signals` The subresource URL of the
// DirectFromSellerSignals for the seller, as produced by concatenating the
// `directFromSellerSignals` URL prefix field passed from runAdAuction() with
// "?sellerSignals". Since this is fetched from a subresource bundle, it may
// only be fetched using the URLLoaderFactory passed in when creating the
// worklet.
//
// `direct_from_seller_seller_signals_header_ad_slot` A JSON string of the
// DirectFromSellerSignals for the seller. Must not be passed if
// `direct_from_seller_seller_signals` or
// `direct_from_seller_auction_signals` is passed.
//
// `direct_from_seller_auction_signals` The subresource URL of the
// directFromSellerSignals for the seller and all buyers, as produced by
// concatenating the `directFromSellerSignals` URL prefix field passed from
// runAdAuction() with "?auctionSignals". Since this is fetched from a
// subresource bundle, it may only be fetched using the URLLoaderFactory
// passed in when creating the worklet.
//
// `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the
// DirectFromSellerSignals for the seller and all buyers. Must not be passed
// if `direct_from_seller_auction_signals` or
// `direct_from_seller_seller_signals` is passed.
//
// `browser_signals_other_seller` The origin of the other seller associated
// with the bid. If this is a component seller worklet, it's the
// top-level seller. If this is a top-level seller scoring a bid from a
// component auction, it's the seller in the component auction.
// Null if this is the top-level seller scoring its own bids.
//
// `browser_signal_interest_group_owner` The owner of the interest group
// that offered the winning bid.
//
// `browser_signal_buyer_and_seller_reporting_id`. If the winning ad
// specified buyerAndSellerReportingId, and that ID passed the appropriate
// k-anonymity check, a value to set as
// browserSignals.buyerAndSellerReportingId will be included here; otherwise
// it is nullopt.
//
// `browser_signal_selected_buyer_and_seller_reporting_id` If the winning bid
// specified selectedBuyerAndSellerReportingId, and that ID passed the
// appropriate k-anonymity check, a value to set as
// browserSignals.selectedBuyerAndSellerReportingId will be included here;
// otherwise it is nullopt.
//
// `browser_signal_render_url` The render URL provided by the winning bid.
//
// `browser_signal_bid` The stochastically rounded numeric value of the
// winning bid.
//
// `browser_signal_bid_currency` The currency the bid is in. This is either
// the sellerCurrency from auction configuration, or unset to denote it's in
// the bidder's currency.
//
// `browser_signal_desirability` The stochastically rounded numeric value of
// the score returned by ScoreAd() for the winning bid.
//
// `browser_signal_highest_scoring_other_bid` The stochastically rounded
// numeric value of the bid that got the second highest score, or 0 if it's
// not available, either because there is no such thing or because no
// currency conversion was performed.
//
// `browser_signal_highest_scoring_other_bid_currency` The currency associated
// with `browser_signal_highest_scoring_other_bid`. This is either the
// sellerCurrency from auction configuration, if it's set, or nullopt to
// denote it's in the bidder's currency.
//
// `browser_signals_component_auction_report_result_params` Extra parameters
// passed to the component auction's ReportResult() method. Should be null
// for top-level sellers.
//
// `scoring_signals_data_version` The value of the Data-Version header served
// with the trusted scoring signals, if the header was present.
//
// `trace_id` ID of a nestable asynchronous trace event of category `fledge`
// to use with tracing calls.
//
// Returns:
// `signals_for_winner` The value to pass to the winning bidder's
// ReportWin function, as a JSON string. Null if no value is provided.
//
// `report_url` The URL to request to report the result of the auction to the
// seller, if any.
//
// `ad_beacon_map` The map of ad reporting events to URLs for fenced frame
// reporting.
//
// `pa_requests` The various requests made to the Private Aggregation API.
//
// `reporting_latency` How long it took to run `reportResult()` JS, including
// the top-level.
//
// `errors` are various error messages to be used for debugging. These are too
// sensitive for the renderers to see. `errors` should not be assumed to be
// empty if the other values are populated, nor should it be assumed to be
// non-empty if the other values are null.
ReportResult(
blink.mojom.AuctionAdConfigNonSharedParams
auction_ad_config_non_shared_params,
url.mojom.Url? direct_from_seller_seller_signals,
string? direct_from_seller_seller_signals_header_ad_slot,
url.mojom.Url? direct_from_seller_auction_signals,
string? direct_from_seller_auction_signals_header_ad_slot,
ComponentAuctionOtherSeller? browser_signals_other_seller,
url.mojom.Origin browser_signal_interest_group_owner,
string? browser_signal_buyer_and_seller_reporting_id,
string? browser_signal_selected_buyer_and_seller_reporting_id,
url.mojom.Url browser_signal_render_url,
double browser_signal_bid,
blink.mojom.AdCurrency? browser_signal_bid_currency,
double browser_signal_desirability,
double browser_signal_highest_scoring_other_bid,
blink.mojom.AdCurrency? browser_signal_highest_scoring_other_bid_currency,
ComponentAuctionReportResultParams?
browser_signals_component_auction_report_result_params,
uint32? scoring_signals_data_version,
uint64 trace_id) =>
(string? signals_for_winner,
url.mojom.Url? report_url,
map<string, url.mojom.Url> ad_beacon_map,
array<PrivateAggregationRequest> pa_requests,
SellerTimingMetrics time_metrics,
array<string> error_msgs);
// Establishes a debugger connection to the worklet thread.
//
// Arguments:
// `thread_index` The index of the thread in the thread pool.
ConnectDevToolsAgent(
pending_associated_receiver<blink.mojom.DevToolsAgent> agent,
uint32 thread_index);
};