blob: e60d91c9e2976e7e90271075c1f459f2f16367e5 [file] [log] [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_INTEREST_GROUP_AUCTION_H_
#define CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_AUCTION_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/browser/interest_group/auction_nonce_manager.h"
#include "content/browser/interest_group/auction_result.h"
#include "content/browser/interest_group/auction_worklet_manager.h"
#include "content/browser/interest_group/bidding_and_auction_response.h"
#include "content/browser/interest_group/header_direct_from_seller_signals.h"
#include "content/browser/interest_group/interest_group_auction_reporter.h"
#include "content/browser/interest_group/interest_group_pa_report_util.h"
#include "content/browser/interest_group/interest_group_storage.h"
#include "content/browser/interest_group/subresource_url_builder.h"
#include "content/common/content_export.h"
#include "content/public/browser/content_browser_client.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/seller_worklet.mojom.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/mojom/client_security_state.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/interest_group/interest_group.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.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace blink {
struct AuctionConfig;
}
namespace content {
class AdAuctionNegativeTargeter;
class AdAuctionPageData;
struct AdAuctionRequestContext;
class AuctionMetricsRecorder;
class BrowserContext;
class InterestGroupManagerImpl;
class PrivateAggregationManager;
struct SignedAdditionalBidSignature;
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBiddingAndAuctionEncryptionMediaType);
CONTENT_EXPORT extern const base::FeatureParam<std::string>
kBiddingAndAuctionEncryptionRequestMediaType;
CONTENT_EXPORT extern const base::FeatureParam<std::string>
kBiddingAndAuctionEncryptionResponseMediaType;
// An InterestGroupAuction Handles running an auction, or a component auction.
// Consumers should use AuctionRunner, which sets up InterestGroupAuction and
// extracts their results. Separate from AuctionRunner so that nested
// InterestGroupAuction can handle component auctions as well as top-level
// auction.
//
// Auctions have two phases, with phase transitions handled by the owner. All
// phases complete asynchronously:
//
// * Loading interest groups phase: This loads interest groups that can
// participate in an auction. Waiting for all component auctions to complete
// this phase before advancing to the next ensures that if any auctions share
// bidder worklets, they'll all be loaded together, and only send out a single
// trusted bidding signals request.
//
// * Bidding/scoring phase: This phase loads bidder and seller worklets,
// generates bids, scores bids, and the highest scoring bid for each component
// auction is passed to its parent auction, which also scores it. When this
// phase completes, the winner will have been decided.
class CONTENT_EXPORT InterestGroupAuction
: public auction_worklet::mojom::ScoreAdClient {
public:
// Post auction signals (signals only available after auction completes such
// as winning bid) for debug loss/win reporting.
struct CONTENT_EXPORT PostAuctionSignals {
PostAuctionSignals();
// For now, top-level post auction signals do not have
// `highest_scoring_other_bid` information.
PostAuctionSignals(double winning_bid,
absl::optional<blink::AdCurrency> winning_bid_currency,
bool made_winning_bid);
PostAuctionSignals(
double winning_bid,
absl::optional<blink::AdCurrency> winning_bid_currency,
bool made_winning_bid,
double highest_scoring_other_bid,
absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency,
bool made_highest_scoring_other_bid);
~PostAuctionSignals();
PostAuctionSignals(PostAuctionSignals&) = delete;
PostAuctionSignals& operator=(PostAuctionSignals&) = delete;
// Computes appropriate information to provide for winningBid information,
// dependent on whether bidder-currency or seller-currency is expected.
static void FillWinningBidInfo(
const url::Origin& owner,
absl::optional<url::Origin> winner_owner,
double winning_bid,
absl::optional<double> winning_bid_in_seller_currency,
const absl::optional<blink::AdCurrency>& seller_currency,
bool& out_made_winning_bid,
double& out_winning_bid,
absl::optional<blink::AdCurrency>& out_winning_bid_currency);
// Computes appropriate information to provide for highestScoringOtherBid
// information, dependent on whether bidder-currency or seller-currency is
// expected.
static void FillRelevantHighestScoringOtherBidInfo(
const url::Origin& owner,
absl::optional<url::Origin> highest_scoring_other_bid_owner,
double highest_scoring_other_bid,
absl::optional<double> highest_scoring_other_bid_in_seller_currency,
const absl::optional<blink::AdCurrency>& seller_currency,
bool& out_made_highest_scoring_other_bid,
double& out_highest_scoring_other_bid,
absl::optional<blink::AdCurrency>&
out_highest_scoring_other_bid_currency);
double winning_bid = 0.0;
absl::optional<blink::AdCurrency> winning_bid_currency;
bool made_winning_bid = false;
double highest_scoring_other_bid = 0.0;
absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency;
bool made_highest_scoring_other_bid = false;
};
// Returns true if `origin` is allowed to use the interest group API. Will be
// called on worklet / interest group origins before using them in any
// interest group API.
using IsInterestGroupApiAllowedCallback = base::RepeatingCallback<bool(
ContentBrowserClient::InterestGroupApiOperation
interest_group_api_operation,
const url::Origin& origin)>;
using PrivateAggregationRequests =
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>;
// Helps determine which level of worklet a particular PA request came from.
enum class PrivateAggregationPhase {
kBidder,
kNonTopLevelSeller, // Seller for a component auction.
kTopLevelSeller, // Top-level seller, either with components or
// as the sole seller in a single-seller auction.
kNumPhases
};
struct CONTENT_EXPORT BidState {
BidState();
~BidState();
BidState(BidState&&);
BidState& operator=(BidState&&);
// Disable copy and assign, since this struct owns a
// auction_worklet::mojom::BiddingInterestGroupPtr, and mojo classes are not
// copiable.
BidState(BidState&) = delete;
BidState& operator=(BidState&) = delete;
// Populates `trace_id` with a new trace ID and logs the first trace event
// for it.
void BeginTracing();
// Logs the final event for `trace_id` and clears it. Automatically called
// on destruction so trace events are all closed if an auction is cancelled.
void EndTracing();
// Like above but for `trace_id_for_kanon_scoring`, and used specifically
// for scoring of auction entries that were re-run due to k-anonymity
// enforcement.
void BeginTracingKAnonScoring();
void EndTracingKAnonScoring();
// Use a unique pointer so this can be more safely moved to the
// InterestGroupAuctionReporter. Doing so both preserves pointers, and make
// sure there's a crash if this is dereferenced after move.
std::unique_ptr<StorageInterestGroup> bidder;
// Set of render keys that are k-anonymous and correspond to ad or ad
// component render URLs for this interest group.
// (Not set if we are not configured to care).
base::flat_map<std::string, bool> kanon_keys;
// This starts off as the base priority of the interest group, but is
// updated by sparse vector multiplications using first the priority vector
// from the interest group, and then the one received from the trusted
// server, if appropriate.
double calculated_priority;
// Holds a reference to the BidderWorklet, once created.
std::unique_ptr<AuctionWorkletManager::WorkletHandle> worklet_handle;
// Tracing ID associated with the BidState. A nestable async "Bid" trace
// event is started for a bid state during the generate and score bid phase
// when the worklet is requested, and ended once the bid is scored, or the
// bidder worklet fails to bid.
//
// Additionally, if the BidState is a winner of a component auction, another
// "Bid" trace event is created when the top-level auction scores the bid,
// and ends when scoring is complete.
//
// Nested events are logged using this ID both by the Auction and by Mojo
// bidder and seller worklets, potentially in another process.
//
// absl::nullopt means no ID is currently assigned, and there's no pending
// event.
absl::optional<uint64_t> trace_id;
// Since the k-anon-enforced scoring creates events that don't nest neatly
// with the regular run, it gets its own id.
absl::optional<uint64_t> trace_id_for_kanon_scoring;
// ReceiverId for use as a GenerateBidClient. Only populated while
// generateBid() is running.
absl::optional<mojo::ReceiverId> generate_bid_client_receiver_id;
// Mojo pipe to use to fill in potentially promise-provided arguments.
// Only populated in between BeginGenerateBid and FinishGenerateBid().
mojo::AssociatedRemote<auction_worklet::mojom::GenerateBidFinalizer>
bid_finalizer;
// True when OnBiddingSignalsReceived() has been invoked. Needed to
// correctly handle the case the bidder worklet pipe is closed before
// OnBiddingSignalsReceived() is invoked.
bool bidding_signals_received = false;
// Callback to resume generating a bid after OnBiddingSignalsReceived() has
// been invoked. Only used when `enabled_bidding_signals_prioritization` is
// true for any interest group with the same owner, while waiting for all
// interest groups to receive their final priorities. In other cases, the
// callback is invoked immediately.
base::OnceClosure resume_generate_bid_callback;
// This is true if after this bid would be a good time to combine pending
// trusted signals requests on its worklet and flush them. Currently set
// when this is the last bid requested of the worklet.
bool send_pending_trusted_signals_after_generate_bid = false;
// Used to avoid sending direct-from-seller signals twice if they are
// available by time of GenerateBid(). This can be true even if no signals
// are actually available, just so long as that's known.
bool handled_direct_from_seller_signals_in_begin_generate_bid = false;
// True if the worklet successfully made a bid.
bool made_bid = false;
// If this was provided as an additional bid, this is set to the origin it
// claims to be.
absl::optional<url::Origin> additional_bid_buyer;
// URLs of forDebuggingOnly.reportAdAuctionLoss(url) and
// forDebuggingOnly.reportAdAuctionWin(url) called in generateBid().
// They support post auction signal placeholders in their query string, for
// example, "https://example.com/?${winningBid}".
// Placeholders will be replaced by corresponding values. For a component
// auction, post auction signals are only from the component auction, but
// not the top-level auction.
absl::optional<GURL> bidder_debug_loss_report_url;
absl::optional<GURL> bidder_debug_win_report_url;
// URLs of forDebuggingOnly.reportAdAuctionLoss(url) and
// forDebuggingOnly.reportAdAuctionWin(url) called in scoreAd(). In the case
// of a component auction, these are the values from component seller that
// the scored ad was created in, and post auction signals are from both the
// component auction and top-level auction.
absl::optional<GURL> seller_debug_loss_report_url;
absl::optional<GURL> seller_debug_win_report_url;
// URLs of forDebuggingOnly.reportAdAuctionLoss(url) and
// forDebuggingOnly.reportAdAuctionWin(url) called in scoreAd() from the
// top-level seller, in the case this bidder was made in a component
// auction, won it, and was then scored by the top-level seller.
absl::optional<GURL> top_level_seller_debug_win_report_url;
absl::optional<GURL> top_level_seller_debug_loss_report_url;
// Requests made to Private aggregation API in generateBid() and scoreAd().
// Keyed by reporting origin of the associated requests, i.e., buyer origin
// for generateBid() and seller origin for scoreAd(), plus an enum that
// determines exactly which phase of the auction made that request.
//
// TODO(qingxinwu): Consider only saving the requests without saving Origin,
// since copying Origin is expensive.
std::map<std::pair<url::Origin, PrivateAggregationPhase>,
PrivateAggregationRequests>
private_aggregation_requests;
// Requests made to Private aggregation API in generateBid() for the
// non-k-anonymous enforced bid when k-anonymity enforcement is active.
PrivateAggregationRequests non_kanon_private_aggregation_requests;
PrivateAggregationTimings private_aggregation_timings[static_cast<int>(
PrivateAggregationPhase::kNumPhases)];
PrivateAggregationTimings& pa_timings(PrivateAggregationPhase phase) {
return private_aggregation_timings[static_cast<int>(phase)];
}
// The reason this bid was rejected by the auction (i.e., reason why score
// was non-positive).
auction_worklet::mojom::RejectReason reject_reason =
auction_worklet::mojom::RejectReason::kNotAvailable;
};
// Result of generated a bid. Contains information that needs to score a bid
// and is persisted to the end of the auction if the bidder wins. Largely
// duplicates auction_worklet::mojom::BidderWorkletBid, with additional
// information about the bidder.
struct CONTENT_EXPORT Bid {
// Which auctions the bid is appropriate for, based on whether the auction
// enforces k-anonymity or not.
enum class BidRole { kUnenforcedKAnon, kEnforcedKAnon, kBothKAnonModes };
Bid(BidRole bid_role,
std::string ad_metadata,
double bid,
absl::optional<blink::AdCurrency> bid_currency,
absl::optional<double> ad_cost,
blink::AdDescriptor ad_descriptor,
std::vector<blink::AdDescriptor> ad_component_descriptors,
absl::optional<uint16_t> modeling_signals,
base::TimeDelta bid_duration,
absl::optional<uint32_t> bidding_signals_data_version,
const blink::InterestGroup::Ad* bid_ad,
BidState* bid_state,
InterestGroupAuction* auction);
Bid(Bid&);
~Bid();
// This considers the bid_role to pick proper trace id.
uint64_t TraceId() {
return (bid_role == BidRole::kEnforcedKAnon)
? *bid_state->trace_id_for_kanon_scoring
: *bid_state->trace_id;
}
// Get a vector of ad component urls. For compatible with functions
// expecting a vector of `GURL` instead of a vector of
// `blink::AdDescriptor`.
std::vector<GURL> GetAdComponentUrls() const;
// Which auctions the bid participates in.
BidRole bid_role;
// These are taken directly from the
// auction_worklet::mojom::BidderWorkletBid.
const std::string ad_metadata;
const double bid;
const absl::optional<blink::AdCurrency> bid_currency;
const absl::optional<double> ad_cost;
const blink::AdDescriptor ad_descriptor;
const std::vector<blink::AdDescriptor> ad_component_descriptors;
const absl::optional<uint16_t> modeling_signals;
const base::TimeDelta bid_duration;
const absl::optional<uint32_t> bidding_signals_data_version;
// InterestGroup that made the bid. Owned by the BidState of that
// InterestGroup.
raw_ptr<const blink::InterestGroup> interest_group;
// Points to the InterestGroupAd within `interest_group`.
raw_ptr<const blink::InterestGroup::Ad> bid_ad;
// `bid_state` of the InterestGroup that made the bid. This should not be
// written to, except for adding seller debug reporting URLs.
const raw_ptr<BidState> bid_state;
// The Auction with the interest group that made this bid. Important in the
// case of component auctions.
const raw_ptr<InterestGroupAuction> auction;
// Time where tracing for wait_seller_deps began; if it ever did.
base::TimeTicks trace_wait_seller_deps_start;
// How long various inputs were waited for.
base::TimeDelta wait_worklet;
base::TimeDelta wait_promises;
// Time we called ScoreAd on the SellerWorklet.
base::TimeTicks seller_worklet_score_ad_start;
};
// Combines a Bid with seller score and seller state needed to invoke its
// ReportResult() method.
struct ScoredBid {
ScoredBid(double score,
absl::optional<uint32_t> scoring_signals_data_version,
std::unique_ptr<Bid> bid,
absl::optional<double> bid_in_seller_currency,
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
component_auction_modified_bid_params);
~ScoredBid();
// The seller's desirability score for the bid.
const double score;
// The seller's scoring signals version.
const absl::optional<uint32_t> scoring_signals_data_version;
// The bid that came from the bidder or component Auction.
const std::unique_ptr<Bid> bid;
// Bidder's bid currency-converted by the seller to seller's own currency.
const absl::optional<double> bid_in_seller_currency;
// Modifications that should be applied to `bid` before the parent
// auction uses it. Only present for bids in component Auctions. When
// the top-level auction creates a ScoredBid represending the result from
// a component auction, the params have already been applied to the
// underlying Bid, so the params are no longer needed.
const auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
component_auction_modified_bid_params;
};
// Callback that's called when a phase of the InterestGroupAuction completes.
// Always invoked asynchronously.
using AuctionPhaseCompletionCallback = base::OnceCallback<void(bool success)>;
// All passed in raw pointers must remain valid until the InterestGroupAuction
// is destroyed. `config` is typically owned by the AuctionRunner's
// `owned_auction_config_` field. `parent` should be the parent
// InterestGroupAuction if this is a component auction, and null, otherwise.
//
// `is_interest_group_api_allowed_callback` will be used to check whether the
// sellers of the auction and bids provided via interest groups or
// additionalBids are permitted to participate.
InterestGroupAuction(
auction_worklet::mojom::KAnonymityBidMode kanon_mode,
const blink::AuctionConfig* config,
const InterestGroupAuction* parent,
AuctionWorkletManager* auction_worklet_manager,
AuctionNonceManager* auction_nonce_manager,
InterestGroupManagerImpl* interest_group_manager,
AuctionMetricsRecorder* auction_metrics_recorder,
base::Time auction_start_time,
IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback,
base::RepeatingCallback<
void(const PrivateAggregationRequests& private_aggregation_requests)>
maybe_log_private_aggregation_web_features_callback);
InterestGroupAuction(const InterestGroupAuction&) = delete;
InterestGroupAuction& operator=(const InterestGroupAuction&) = delete;
~InterestGroupAuction() override;
// Starts loading the interest groups that can participate in an auction.
//
// Both seller and buyer origins are filtered by
// `is_interest_group_api_allowed` passed to the constructor, and any any not
// allowed to use the API are excluded from participating in the auction.
//
// Invokes `load_interest_groups_phase_callback` asynchronously on
// completion. Passes it false if there are no interest groups that may
// participate in the auction (possibly because sellers aren't allowed to
// participate in the auction)
void StartLoadInterestGroupsPhase(
AuctionPhaseCompletionCallback load_interest_groups_phase_callback);
// Starts bidding and scoring phase of the auction.
//
// `on_seller_receiver_callback`, if non-null, is invoked once the seller
// worklet has been received, or if the seller worklet is no longer needed
// (e.g., if all bidders fail to bid before the seller worklet has
// been received). This is needed so that in the case of component auctions,
// the top-level seller worklet will only be requested once all component
// seller worklets have been received, to prevent deadlock (the top-level
// auction could be waiting on a bid from a seller, while the top-level
// seller worklet being is blocking a component seller worklet from being
// created, due to the process limit). Unlike other callbacks,
// `on_seller_receiver_callback` may be called synchronously.
//
// `bidding_and_scoring_phase_callback` is invoked asynchronously when
// either the auction has failed to produce a winner, or the auction has a
// winner. `success` is true only when there is a winner.
void StartBiddingAndScoringPhase(
base::OnceClosure on_seller_receiver_callback,
AuctionPhaseCompletionCallback bidding_and_scoring_phase_callback);
// Starts an auction based on a server response.
void StartFromServerResponse(
mojo_base::BigBuffer response,
AdAuctionPageData* ad_auction_page_data,
AuctionPhaseCompletionCallback bidding_and_scoring_phase_callback);
// Creates an InterestGroupAuctionReporter, after the auction has completed.
// Takes ownership of the `auction_config`, so that the reporter can outlive
// other auction-related classes. This also means that various method on
// `this` that use the configuration should not be called past this point.
std::unique_ptr<InterestGroupAuctionReporter> CreateReporter(
BrowserContext* browser_context,
PrivateAggregationManager* private_aggregation_manager,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<blink::AuctionConfig> auction_config,
const url::Origin& main_frame_origin,
const url::Origin& frame_origin,
network::mojom::ClientSecurityStatePtr client_security_state,
blink::InterestGroupSet interest_groups_that_bid);
// Called by AuctionRunner (for component auctions, indirectly via
// NotifyComponentConfigPromisesResolved) when all promises relevant to this
// particular auction have been resolved (not called when there were no
// promises to wait for to start with).
void NotifyConfigPromisesResolved();
// Called by AuctionRunner when all promises relevant to component auction
// with position `pos` in the original configuration have been resolved.
//
// Assumes that `pos` has already been range-checked, and that this is
// a parent auction.
void NotifyComponentConfigPromisesResolved(uint32_t pos);
// Called by AuctionRunner when the promise providing the additional_bids
// array has been resolved, if one exists. Unlike other similar methods,
// `auction_page_data` may be null.
void NotifyAdditionalBidsConfig(AdAuctionPageData* auction_page_data);
// Called by AuctionRunner when the promise for `additional_bids` for
// component auction with position `pos` in the original configuration has
// been resolved.
//
// Assumes that `pos` has already been range-checked, and that this is
// a parent auction.
//
// Unlike other similar methods, `auction_page_data` may be null.
void NotifyComponentAdditionalBidsConfig(
uint32_t pos,
AdAuctionPageData* auction_page_data);
// Called by AuctionRunner when the promise providing the
// `direct_from_seller_signals_header_ad_slot` string has been resolved, if
// one exists.
//
// The implementation must not hold on to `auction_page_data` after returning,
// since `auction_page_data` can be freed when navigating away.
void NotifyDirectFromSellerSignalsHeaderAdSlotConfig(
AdAuctionPageData* auction_page_data,
const absl::optional<std::string>&
direct_from_seller_signals_header_ad_slot);
// Called by AuctionRunner when the value of
// `direct_from_seller_signals_header_ad_slot` for component
// auction with position `pos` in the original configuration has been
// resolved.
//
// Assumes that `pos` has already been range-checked, and that this is
// a parent auction.
//
// The implementation must not hold on to `auction_page_data` after returning,
// since `auction_page_data` can be freed when navigating away.
void NotifyComponentDirectFromSellerSignalsHeaderAdSlotConfig(
uint32_t pos,
AdAuctionPageData* auction_page_data,
const absl::optional<std::string>&
direct_from_seller_signals_header_ad_slot);
// Close all Mojo pipes and release all weak pointers. Called when an
// auction fails and on auction complete.
void ClosePipes();
// Returns the number of interest groups participating in the auction that can
// potentially make bids. Includes interest groups in component auctions.
// Double-counts interest groups participating multiple times in different
// InterestGroupAuctions. Does not include synthetic interest groups for
// additional bids.
size_t NumPotentialBidders() const;
// Returns all interest groups that bid in an auction. Expected to be called
// after the bidding and scoring phase completes. Returns an empty set if the
// auction failed for any reason other than the seller rejecting all bids.
// Bids from additional bids are not included, since they do not really have
// interest groups (and we don't want to attribute them to database IGs with
// aliasing names).
void GetInterestGroupsThatBidAndReportBidCounts(
blink::InterestGroupSet& interest_groups) const;
// Returns the requested ad size specified by the auction config. Called
// after the bidding and scoring phase completes, to set the container size
// in the fenced frame config resulting from the auction.
absl::optional<blink::AdSize> RequestedAdSize() const;
// Retrieves any debug reporting URLs. May only be called once, since it takes
// ownership of stored reporting URLs. This is called internally by
// CreateReporter() so may only be called in the case an auction has no
// winner, and thus CreateReporter() need not be called.
//
// Note: Temporarily, this function also fills post auction signals to private
// aggregation requests from generateBid() and scoreAd(), so this function
// must be called before TakePrivateAggregationRequests() to make sure that
// function gets private aggregation requests with post auction signals filled
// in.
// TODO(qingxinwu): Refactor this to fill post auction signals to private
// aggregation report in TakePrivateAggregationRequests(), ideally reuse the
// post auction signals calculated from this method.
void TakeDebugReportUrlsAndFillInPrivateAggregationRequests(
std::vector<GURL>& debug_win_report_urls,
std::vector<GURL>& debug_loss_report_urls);
// Retrieves all requests with reserved event type to the Private Aggregation
// API returned by GenerateBid() and ScoreAd(). The return value is keyed by
// reporting origin of the associated requests. May only be called by external
// consumers after an auction has failed (on success, used internally to pass
// them to the InterestGroupAuctionReporter). May only be called once, since
// it takes ownership of stored reporting URLs.
std::map<url::Origin, PrivateAggregationRequests>
TakeReservedPrivateAggregationRequests();
// Retrieves all requests with non-reserved event type to the Private
// Aggregation API returned by GenerateBid(). The return value is keyed by
// event type of the associated requests. May only be called by external
// consumers after an auction has failed (on success, used internally to pass
// them to the InterestGroupAuctionReporter). May only be called once, since
// it takes ownership of stored reporting URLs.
std::map<std::string, PrivateAggregationRequests>
TakeNonReservedPrivateAggregationRequests();
// Retrieves any errors from the auction. May only be called once, since it
// takes ownership of stored errors.
std::vector<std::string> TakeErrors();
// Retrieves (by appending) all owners of interest groups that participated
// in this auction (or any of its child auctions) that successfully loaded
// at least one interest group. May only be called after the auction has
// completed, for either success or failure. Duplication is possible,
// particularly if an owner is listed in multiple auction components. May
// only be called once, since it moves the stored origins.
void TakePostAuctionUpdateOwners(std::vector<url::Origin>& owners);
// Reports (via extended private aggregation) the number of interest groups
// loaded for the owner of `interest_group` iff `interest_group` has
// authorized this auction's seller to receive such information.
//
// The reported value isn't limited by the auction config's
// perBuyerGroupLimits.
//
// Returns true iff a report was issued.
bool ReportInterestGroupCount(const blink::InterestGroup& interest_group,
size_t count);
// Reports (via extended private aggregation) the number of interest groups
// that bid for the owner of `interest_group` iff `interest_group` has
// authorized this auction's seller to receive such information.
//
// Returns true iff a report was issued.
bool ReportBidCount(const blink::InterestGroup& interest_group, size_t count);
// Reports (via extended private aggregation) the time taken to fetch trusted
// signals iff `interest_group` has authorized this auction's seller to
// receive such information.
void ReportTrustedSignalsFetchLatency(
const blink::InterestGroup& interest_group,
base::TimeDelta trusted_signals_fetch_latency);
// Reports (via extended private aggregation) the time taken to perform
// bidding (including the pre-kanonymous bid, and failed bids) iff
// `interest_group` has authorized this auction's seller to receive such
// information.
void ReportBiddingLatency(const blink::InterestGroup& interest_group,
base::TimeDelta bidding_latency);
// Retrieves the keys that need to be joined as a result of the auction. A
// failed auction may result in keys that still need to be joined, for
// instance if the reason the auction failed was that none of the bids were
// k-anonymous.
//
// If CreateReporter() is invoked, the returned reporter will automatically
// join the k-anon sets if it's informed the winning ad has been navigated to,
// so there's no need for anything else to invoke this method.
base::flat_set<std::string> GetKAnonKeysToJoin() const;
BiddingAndAuctionResponse TakeBiddingAndAuctionResponse() {
return std::move(saved_response_).value();
}
// Depending on the requests present and whether the features have already
// been logged for this page, may log one or more Private Aggregation API web
// features.
void MaybeLogPrivateAggregationWebFeatures(
const std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>&
private_aggregation_requests);
// Returns the top bid of whichever auction (k-anon or not, depending on the
// configuration) is actually to be used for the user-facing results. May only
// be invoked after the bidding and scoring phase has completed. Will be null
// if there is no winner.
ScoredBid* top_bid() const { return leader_info().top_bid.get(); }
// Final result of the auction, once completed. Null before completion.
absl::optional<AuctionResult> final_auction_result() const {
return final_auction_result_;
}
// Gets the buyer experiment ID in `config` for buyer. Public so that
// InterestGroupAuctionReporter can use it.
static absl::optional<uint16_t> GetBuyerExperimentId(
const blink::AuctionConfig& config,
const url::Origin& buyer);
// Gets the buyer per-buyer-signals in `config` for buyer. Public so that
// InterestGroupAuctionReporter can use it.
static absl::optional<std::string> GetPerBuyerSignals(
const blink::AuctionConfig& config,
const url::Origin& buyer);
// Gets the DirectFromSellerSignals auction-signals. Public so that
// InterestGroupAuctionReporter can use it.
static absl::optional<GURL> GetDirectFromSellerAuctionSignals(
const SubresourceUrlBuilder* subresource_url_builder);
// Gets the DirectFromSellerSignalsHeaderAdSlot auction-signals. Public so
// that InterestGroupAuctionReporter can use it.
static absl::optional<std::string>
GetDirectFromSellerAuctionSignalsHeaderAdSlot(
const HeaderDirectFromSellerSignals& signals);
// Gets the buyer DirectFromSellerSignals per-buyer-signals in `config` for
// buyer. Public so that InterestGroupAuctionReporter can use it.
static absl::optional<GURL> GetDirectFromSellerPerBuyerSignals(
const SubresourceUrlBuilder* subresource_url_builder,
const url::Origin& owner);
// Gets the buyer DirectFromSellerSignalsHeaderAdSlot per-buyer-signals
// for `owner`. Public so that InterestGroupAuctionReporter can use it.
static absl::optional<std::string>
GetDirectFromSellerPerBuyerSignalsHeaderAdSlot(
const HeaderDirectFromSellerSignals& signals,
const url::Origin& owner);
// Gets DirectFromSellerSignals seller-signals. Public so that
// InterestGroupAuctionReporter can use it.
static absl::optional<GURL> GetDirectFromSellerSellerSignals(
const SubresourceUrlBuilder* subresource_url_builder);
// Gets DirectFromSellerSignalsHeaderAdSlot seller-signals. Public so that
// InterestGroupAuctionReporter can use it.
static absl::optional<std::string>
GetDirectFromSellerSellerSignalsHeaderAdSlot(
const HeaderDirectFromSellerSignals& signals);
// Replaces `${}` placeholders in a debug report URL's query string for post
// auction signals if exist. Only replaces unescaped placeholder ${}, but
// not escaped placeholder (i.e., %24%7B%7D).
static GURL FillPostAuctionSignals(
const GURL& url,
const PostAuctionSignals& signals,
const absl::optional<PostAuctionSignals>& top_level_signals =
absl::nullopt,
const absl::optional<auction_worklet::mojom::RejectReason> reject_reason =
absl::nullopt);
private:
// Note: this needs to be a type with iterator stability, since we both pass
// iterators around and remove things from here.
using AuctionMap = std::map<uint32_t, std::unique_ptr<InterestGroupAuction>>;
// BuyerHelpers create and own the BidStates for a particular buyer, to
// better handle per-buyer cross-interest-group behavior (e.g., enforcing
// a shared per-buyer timeout, only generating bids for the highest priority N
// interest groups of a particular buyer, etc).
class BuyerHelper;
struct LeaderInfo {
LeaderInfo();
~LeaderInfo();
LeaderInfo(const LeaderInfo&) = delete;
LeaderInfo& operator=(LeaderInfo&) = delete;
// The highest scoring bid so far. Null if no bid has been accepted yet.
std::unique_ptr<ScoredBid> top_bid;
// Number of bidders with the same score as `top_bid`.
size_t num_top_bids = 0;
// Number of bidders with the same score as `second_highest_score`. If the
// second highest score matches the highest score, this does not include the
// top bid.
size_t num_second_highest_bids = 0;
// The numeric value of the bid that got the second highest score. When
// there's a tie for the second highest score, one of the second highest
// scoring bids is randomly chosen.
double highest_scoring_other_bid = 0.0;
absl::optional<double> highest_scoring_other_bid_in_seller_currency;
double second_highest_score = 0.0;
// Whether all bids of the highest score are from the same interest group
// owner.
bool at_most_one_top_bid_owner = true;
// Will be null in the end if there are interest groups having the second
// highest score with different owners. That includes the top bid itself, in
// the case there's a tie for the top bid.
absl::optional<url::Origin> highest_scoring_other_bid_owner;
};
// ---------------------------------
// Load interest group phase methods
// ---------------------------------
// Invoked whenever the interest groups for a buyer have loaded. Adds
// `interest_groups` to `bid_states_`.
void OnInterestGroupRead(std::vector<StorageInterestGroup> interest_groups);
// Invoked when the interest groups for an entire component auction have
// loaded. If `success` is false, removes the component auction.
void OnComponentInterestGroupsRead(AuctionMap::iterator component_auction,
bool success);
// Invoked when the interest groups for a buyer or for an entire component
// auction have loaded. Completes the loading phase if no pending loads
// remain.
void OnOneLoadCompleted();
// Invoked once the interest group load phase has completed. Never called
// synchronously from StartLoadInterestGroupsPhase(), to avoid reentrancy
// (AuctionRunner::callback_ cannot be invoked until
// AuctionRunner::CreateAndStart() completes). `auction_result` is the
// result of trying to load the interest groups that can participate in the
// auction. It's AuctionResult::kSuccess if there are interest groups that
// can take part in the auction, and a failure value otherwise.
void OnStartLoadInterestGroupsPhaseComplete(AuctionResult auction_result);
// -------------------------------------
// Generate and score bids phase methods
// -------------------------------------
// Called when a component auction has received a worklet. Calls
// RequestSellerWorklet() if all component auctions have received worklets.
// See StartBiddingAndScoringPhase() for discussion of this.
void OnComponentSellerWorkletReceived();
// Requests a seller worklet from the AuctionWorkletManager.
void RequestSellerWorklet();
// True if all async prerequisites for calling ScoreBid on the SellerWorklet
// are done.
bool ReadyToScoreBids() const {
return seller_worklet_received_ && config_promises_resolved_ &&
!direct_from_seller_signals_header_ad_slot_pending_;
}
// True if the auction may have additional bids participating.
bool MayHaveAdditionalBids() const {
return config_->expects_additional_bids ||
!encoded_signed_additional_bids_.empty() ||
!bid_states_for_additional_bids_.empty();
}
// Called when RequestSellerWorklet() returns. Starts scoring bids, if there
// are any and config has been resolved.
void OnSellerWorkletReceived();
// Score bids if both the seller worklet and config with all promises resolved
// are ready.
void ScoreQueuedBidsIfReady();
// If we're in the bidding and scoring phase, and
// `encoded_signed_additional_bids_` has been filled in, starts of the process
// of converting these into actual bids, keeping track of it via
// `num_scoring_dependencies_`.
void DecodeAdditionalBidsIfReady();
// Processes a singled signed additional bid.
void HandleDecodedSignedAdditionalBid(
data_decoder::DataDecoder::ValueOrError result);
// Processes payload of a single additionalBids entry.
// `signatures` are the signatures it was supposedly signed with.
// `valid_signatures` are the indices of signatures in `signatures` that
// actually verify.
void HandleDecodedAdditionalBid(
const std::vector<SignedAdditionalBidSignature>& signatures,
const std::vector<size_t>& valid_signatures,
data_decoder::DataDecoder::ValueOrError result);
// Invoked by the AuctionWorkletManager on fatal errors, at any point after
// a SellerWorklet has been provided. Results in auction immediately
// failing.
void OnSellerWorkletFatalError(
AuctionWorkletManager::FatalErrorType fatal_error_type,
const std::vector<std::string>& errors);
// True if all bids have been generated (or decoded from additional_bids) and
// scored and all config promises resolved.
bool IsBiddingAndScoringPhaseComplete() const {
CHECK(started_bidding_and_scoring_phase_);
return num_scoring_dependencies_ == 0 && bids_being_scored_ == 0 &&
unscored_bids_.empty();
}
// Invoked when a component auction completes. If `success` is true, gets
// the Bid from `component_auction` and passes a copy of it to ScoreBid().
void OnComponentAuctionComplete(InterestGroupAuction* component_auction,
bool success);
static std::unique_ptr<Bid> CreateBidFromComponentAuctionWinner(
const ScoredBid* scored_bid,
Bid::BidRole bid_role);
// Called when a potential source of bids or other scoring dependency has
// finished. This could be a component auction completing (with or without
// generating a bid) or a BuyerHelper that has finished generating bids.
// Bid scores should pass their bids to ScoreBidIfReady() before calling this.
// It can also be called when all the config promises got resolved, if that
// happens during the bidding and scoring phase.
//
// Updates `num_scoring_dependencies_`, flushes pending scoring signals
// requests, and advances to the next state of the auction, if the bidding and
// scoring phase is complete.
void OnScoringDependencyDone();
// Calls into the seller asynchronously to score the passed in bid.
void ScoreBidIfReady(std::unique_ptr<Bid> bid);
// Validates the passed in result from ScoreBidComplete(). On failure, reports
// a bad message to the active receiver in `score_ad_receivers_` and returns
// false.
bool ValidateScoreBidCompleteResult(
double score,
auction_worklet::mojom::ComponentAuctionModifiedBidParams*
component_auction_modified_bid_params,
absl::optional<double> bid_in_seller_currency,
const absl::optional<GURL>& debug_loss_report_url,
const absl::optional<GURL>& debug_win_report_url);
// auction_worklet::mojom::ScoreAdClient implementation:
void OnScoreAdComplete(
double score,
auction_worklet::mojom::RejectReason reject_reason,
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
component_auction_modified_bid_params,
absl::optional<double> bid_in_seller_currency,
absl::optional<uint32_t> scoring_signals_data_version,
const absl::optional<GURL>& debug_loss_report_url,
const absl::optional<GURL>& debug_win_report_url,
PrivateAggregationRequests pa_requests,
base::TimeDelta scoring_latency,
auction_worklet::mojom::ScoreAdDependencyLatenciesPtr
score_ad_dependency_latencies,
const std::vector<std::string>& errors) override;
PrivateAggregationPhase seller_phase() const {
return parent_ ? PrivateAggregationPhase::kNonTopLevelSeller
: PrivateAggregationPhase::kTopLevelSeller;
}
// Compares `bid` with current auction leaders in `leader_info`, updating
// `leader_info` if needed.
void UpdateAuctionLeaders(
std::unique_ptr<Bid> bid,
double score,
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
component_auction_modified_bid_params,
absl::optional<double> bid_in_seller_currency,
absl::optional<uint32_t> scoring_signals_data_version,
LeaderInfo& leader_info);
// Invoked when the bid becomes the new highest scoring other bid, to handle
// calculation of post auction signals. `owner` is nullptr in the event the
// bid is tied with the top bid, and they have different origins.
void OnNewHighestScoringOtherBid(
double score,
double bid_value,
absl::optional<double> bid_in_seller_currency,
const url::Origin* owner,
LeaderInfo& leader_info);
absl::optional<base::TimeDelta> SellerTimeout();
// If IsBiddingAndScoringPhaseComplete() is true, completes the bidding and
// scoring phase.
void MaybeCompleteBiddingAndScoringPhase();
// Invoked when the bidding and scoring phase of an auction completes.
// `auction_result` is AuctionResult::kSuccess if the auction has a winner,
// and some other value otherwise. Appends `errors` to `errors_`.
void OnBiddingAndScoringComplete(AuctionResult auction_result,
const std::vector<std::string>& errors = {});
// Like top_bid() but returns all leader information.
const LeaderInfo& leader_info() const;
// These may be null. They should only be invoked after the bidding and
// scoring phase has completed.
ScoredBid* top_kanon_enforced_bid();
const ScoredBid* top_kanon_enforced_bid() const;
ScoredBid* top_non_kanon_enforced_bid();
const ScoredBid* top_non_kanon_enforced_bid() const;
// Fills in `signals_out` and `top_level_signals_out` for reporting for bid
// by `bid_owner` based on the winner.
void ComputePostAuctionSignals(
const url::Origin& bid_owner,
PostAuctionSignals& signals_out,
absl::optional<PostAuctionSignals>& top_level_signals_out);
// -----------------------------------
// Methods not associated with a phase
// -----------------------------------
// Creates a ComponentAuctionOtherSeller to pass to SellerWorklets when
// dealing with `bid`. If `this` is a component auction, returns an object
// with a `top_level_seller`. If this is a top-level auction and `bid` comes
// from a component auction, returns an object with a `component_seller` to
// `bid's` seller.
auction_worklet::mojom::ComponentAuctionOtherSellerPtr GetOtherSellerParam(
const Bid& bid) const;
// Computes a key for a worklet associated with `bid_state`
AuctionWorkletManager::WorkletKey BidderWorkletKey(BidState& bid_state);
// Determines if an extended private aggregation buyers request should be
// made, and if so, issues the request. Otherwise, does nothing.
//
// That is, issues the request if all of the following are true:
//
// 1. `interest_group` has authorized the seller of this auction the
// capability of type `capability`.
//
// 2. `config_`'s `auction_report_buyers` and `auction_report_buyer_keys` have
// requested that such a report be made for the owner of `interest_group`.
//
// 3. `config_`'s `auction_report_buyers` has a key equal to
// `buyer_report_type`.
//
// The issued extended private aggregation report's bucket is calculated from
// `config_`'s `auction_report_buyer_keys` and `auction_report_buyers`, and
// value equals to `value` times the `scalar` from `config_`'s
// `auction_report_buyers`.
//
// Returns true iff a report was issued.
//
// TODO(crbug.com/1416621): Consider pre-aggregating metrics before sending to
// the server.
bool ReportPaBuyersValueIfAllowed(
const blink::InterestGroup& interest_group,
blink::SellerCapabilities capability,
blink::AuctionConfig::NonSharedParams::BuyerReportType buyer_report_type,
int value);
// Returns how and whether k-anonymity is being handled.
auction_worklet::mojom::KAnonymityBidMode kanon_mode() const {
return kanon_mode_;
}
// Returns true if the auction had a non-k-anonymous winner.
bool HasNonKAnonWinner() const;
// Returns true if the non-k-anonymous winner of the auction is k-anonymous.
bool NonKAnonWinnerIsKAnon() const;
// Returns true if this auction (or one of its component auctions)
// successfully loaded some interest groups.
bool HasInterestGroups() const;
// Returns the subresource builder if the promise configuring it has resolved,
// creating it if needed.
SubresourceUrlBuilder* SubresourceUrlBuilderIfReady();
const HeaderDirectFromSellerSignals*
direct_from_seller_signals_header_ad_slot() const {
return direct_from_seller_signals_header_ad_slot_.get();
}
void OnDecompressedServerResponse(
AdAuctionRequestContext* request_context,
base::expected<mojo_base::BigBuffer, std::string> result);
void OnParsedServerResponse(AdAuctionRequestContext* request_context,
data_decoder::DataDecoder::ValueOrError result);
void OnLoadedWinningGroup(BiddingAndAuctionResponse response,
absl::optional<StorageInterestGroup> maybe_group);
// Completion callback for HeaderDirectFromSellerSignals::ParseAndFind(). Sets
// `direct_from_seller_signals_header_ad_slot_`, and sets
// `direct_from_seller_signals_header_ad_slot_pending_` to false, appending
// `errors` to `errors_`.
void OnDirectFromSellerSignalHeaderAdSlotResolved(
std::unique_ptr<HeaderDirectFromSellerSignals> signals,
std::vector<std::string> errors);
// Tracing ID associated with the Auction. A nestable
// async "Auction" trace event lasts for the combined lifetime of `this`
// and a possible InterestGroupAuctionReporter. Sequential events that
// apply to the entire auction are logged using this ID, including
// potentially out-of-process events by bidder and seller worklet
// reporting methods.
//
// Cleared if the ID got transferred to InterestGroupAuctionReporter.
absl::optional<uint64_t> trace_id_;
// Whether k-anonymity enforcement or simulation (or none) are performed.
const auction_worklet::mojom::KAnonymityBidMode kanon_mode_;
const raw_ptr<AuctionWorkletManager> auction_worklet_manager_;
const raw_ptr<AuctionNonceManager> auction_nonce_manager_;
const raw_ptr<InterestGroupManagerImpl> interest_group_manager_;
const raw_ptr<AuctionMetricsRecorder> auction_metrics_recorder_;
// Configuration of this auction.
raw_ptr<const blink::AuctionConfig> config_;
// True once all promises in this and component auction's configuration have
// been resolved. (Note that if `this` is a component auction, it only looks
// at itself; while main auctions do look at their components recursively).
bool config_promises_resolved_ = false;
// Will be set to `true` while parsing JSON to find a matching
// directFromSellerSignalsHeaderAdSlot response. Bid generation will be
// blocked while true, even if promises have all resolved.
bool direct_from_seller_signals_header_ad_slot_pending_ = false;
// If this is a component auction, the parent Auction. Null, otherwise.
const raw_ptr<const InterestGroupAuction> parent_;
// flat_set copy of the interestGroupBuyers from the config, for efficient
// finds. This is only populated when encoded_signed_additional_bids_ is.
base::flat_set<url::Origin> interest_group_buyers_;
// Base64-encoded signed additional bid entries.
std::vector<std::string> encoded_signed_additional_bids_;
// This needs pointer stability for the BidState*.
std::vector<std::unique_ptr<BidState>> bid_states_for_additional_bids_;
// Helper for computing negative targeting for additional bids.
std::unique_ptr<AdAuctionNegativeTargeter> negative_targeter_;
// Component auctions that are part of this auction. This auction manages
// their state transition, and their bids may participate in this auction as
// well. Component auctions that fail in the load phase are removed from
// this map, to avoid trying to load their worklets during the scoring
// phase.
//
// The key of the map is the original index of the auction's AuctionConfig
// in `config_->non_shared_params.component_auctions`; there may be
// discontinuities if some entries got removed in the load phase.
AuctionMap component_auctions_;
// Final result of the auction, once completed. Null before completion.
absl::optional<AuctionResult> final_auction_result_;
// Each phases uses its own callback, to make sure that the right callback
// is invoked when the phase completes.
AuctionPhaseCompletionCallback load_interest_groups_phase_callback_;
AuctionPhaseCompletionCallback bidding_and_scoring_phase_callback_;
// Start time of the BiddingAndScoring phase for UKM metrics.
base::TimeTicks bidding_and_scoring_phase_start_time_;
// Invoked in the bidding and scoring phase, once the seller worklet has
// loaded. May be null.
base::OnceClosure on_seller_receiver_callback_;
// The number of buyers and component auctions with pending interest group
// loads from storage. Decremented each time either the interest groups for
// a buyer or all buyers for a component are read.
// `load_interest_groups_phase_callback` is invoked once this hits 0.
size_t num_pending_loads_ = 0;
// True once a seller worklet has been received from the
// AuctionWorkletManager.
bool seller_worklet_received_ = false;
// True once we enter the bidding and scoring phase.
bool started_bidding_and_scoring_phase_ = false;
// Number of things that are pending that are needed to score everything.
// This includes bidders that are still attempting to generate bids ---
// both BuyerHelpers and component auctions. BuyerHelpers may generate
// multiple bids (or no bids). It also includes waiting for promises in
// configuration to resolve, waiting for directFromSellerSignalsHeaderAdSlot
// to parse, and waiting for additional bids to parse.
//
// When this reaches 0, the SellerWorklet's SendPendingSignalsRequests()
// method should be invoked, so it can send any pending scoring signals
// requests.
int num_scoring_dependencies_ = 0;
// Number of bids that have been send to the seller worklet to score, but
// that haven't yet had their score received from the seller worklet.
int bids_being_scored_ = 0;
// The number of `component_auctions_` that have yet to request seller
// worklets. Once it hits 0, the seller worklet for `this` is loaded. See
// StartBiddingAndScoringPhase() for more details.
size_t pending_component_seller_worklet_requests_ = 0;
bool any_bid_made_ = false;
// State of all buyers participating in the auction. Excludes buyers that
// don't own any interest groups the user belongs to.
std::vector<std::unique_ptr<BuyerHelper>> buyer_helpers_;
// Bids waiting on the seller worklet to load before scoring. Does not
// include bids that are currently waiting on the worklet's ScoreAd() method
// to complete.
std::vector<std::unique_ptr<Bid>> unscored_bids_;
// The time the auction started. Use a single base time for all Worklets, to
// present a more consistent view of the universe.
const base::Time auction_start_time_;
// The time when this InterestGroupAuction was created; used for UMA.
const base::TimeTicks creation_time_;
// Holds the computed subresource URLs (renderer-supplied prefix + browser
// produced suffix). This gets constructed on-demand once the prefix actually
// comes in from a potential promises, and in successful auctions gets
// transferred to InterestGroupAuctionReporter.
std::unique_ptr<SubresourceUrlBuilder> subresource_url_builder_;
// Stores the loaded HeaderDirectFromSellerSignals, if there were any. Should
// never be null until moved to the reporter.
//
// After `direct_from_seller_signals_header_ad_slot_` has been
// set to true, the default constructed value gets replaced with the found
// signals, if the auction config provided an ad-slot, and it matched one of
// the captured responses for the seller's origin.
std::unique_ptr<HeaderDirectFromSellerSignals>
direct_from_seller_signals_header_ad_slot_ =
std::make_unique<HeaderDirectFromSellerSignals>();
// The number of buyers in the AuctionConfig that passed the
// IsInterestGroupApiAllowedCallback filter and interest groups were found
// for. Includes buyers from nested component auctions. Double-counts buyers
// in multiple Auctions.
int num_owners_loaded_ = 0;
// The number of buyers with InterestGroups participating in an auction.
// Includes buyers from nested component auctions, but excludes buyers with
// no ads or no script URL. Double-counts buyers that participate in
// multiple Auctions.
int num_owners_with_interest_groups_ = 0;
// A list of all buyer owners that participated in this auction and had at
// least one interest group. These owners will have their interest groups
// updated after a successful auction, barring rate-limiting.
std::vector<url::Origin> post_auction_update_owners_;
// A list of all interest groups that need to have their priority adjusted.
// The new rates will be committed after a successful auction.
std::vector<std::pair<blink::InterestGroupKey, double>>
post_auction_priority_updates_;
LeaderInfo non_kanon_enforced_auction_leader_;
LeaderInfo kanon_enforced_auction_leader_;
// Holds a reference to the SellerWorklet used by the auction.
std::unique_ptr<AuctionWorkletManager::WorkletHandle> seller_worklet_handle_;
// Stores all pending Private Aggregation API report requests of reserved
// event type from the bidding and scoring phase. These are passed to the
// InterestGroupAuctionReporter when it's created. Keyed by the origin of the
// script that issued the request (i.e. the reporting origin).
std::map<url::Origin, PrivateAggregationRequests>
private_aggregation_requests_reserved_;
// Stores all pending Private Aggregation API report requests of non-reserved
// event type. Only comes from bidding phase of winning buyer. These are
// passed to the InterestGroupAuctionReporter when it's created. Keyed by the
// request's event type.
std::map<std::string, PrivateAggregationRequests>
private_aggregation_requests_non_reserved_;
// Callback for checking who can participate in the auction.
IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback_;
// Callback for passing encountered PrivateAggregationRequests up in order to
// maybe trigger Private Aggregation web features, as appropriate.
base::RepeatingCallback<void(
const PrivateAggregationRequests& private_aggregation_requests)>
maybe_log_private_aggregation_web_features_callback_;
// This is set to true if the actual auction ran on a B&A server and we are
// just handling the response.
bool is_server_auction_ = false;
// Saved response from the server if the actual auction ran on a B&A server.
absl::optional<BiddingAndAuctionResponse> saved_response_;
// Time when `getInterestGroupAdAuctionData()` was called. Only for auctions
// running on B&A servers.
base::TimeTicks get_ad_auction_data_start_time_;
// All errors reported by worklets thus far.
std::vector<std::string> errors_;
// This is set to true if the scoring phase ran and was able to score all
// bids that were made (of which there may have been none). This is used to
// gate accessors that should return nothing if the entire auction failed
// (e.g., don't want to report bids as having "lost" an auction if the
// seller failed to load, since neither the bids nor the bidders were the
// problem).
bool all_bids_scored_ = false;
// Receivers for OnScoreAd() callbacks. Owns Bids, which have raw pointers to
// other objects, so must be last, to avoid triggering tooling to check for
// dangling pointers.
mojo::ReceiverSet<auction_worklet::mojom::ScoreAdClient, std::unique_ptr<Bid>>
score_ad_receivers_;
base::WeakPtrFactory<InterestGroupAuction> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_AUCTION_H_