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);
};