blob: a62981f025aed2823da1f3d622cb3434231d6602 [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_AUCTION_RUNNER_H_
#define CONTENT_BROWSER_INTEREST_GROUP_AUCTION_RUNNER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/memory/raw_ptr.h"
#include "content/browser/interest_group/auction_worklet_manager.h"
#include "content/browser/interest_group/interest_group_auction.h"
#include "content/common/content_export.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom-forward.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.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 InterestGroupAuctionReporter;
class InterestGroupManagerImpl;
// An AuctionRunner loads and runs the bidder and seller worklets, along with
// their reporting phases and produces the result via a callback. Most of the
// logic is handled by InterestGroupAuction, with the AuctionRunner handling
// state transitions and assembling the final results of the auction.
//
// All auctions must be created on the same thread. This is just needed because
// the code to assign unique tracing IDs is not threadsafe.
class CONTENT_EXPORT AuctionRunner : public blink::mojom::AbortableAdAuction {
public:
using PrivateAggregationRequests =
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>;
// Invoked when a FLEDGE auction is complete.
//
// `manually_aborted` is true only if the auction was successfully interrupted
// by the call to Abort().
//
// `winning_group_id` owner and name of the winning interest group (if any).
//
// `render_url` URL of auction winning ad to render. Null if there is no
// winner.
//
// `ad_component_urls` is the list of ad component URLs returned by the
// winning bidder. Null if there is no winner or no list was returned.
//
// `winning_group_ad_metadata` is the metadata associated with the winning ad,
// to be made available to the interest group in future auctions in the
// `prevWins` field. Empty if there was no winner.
//
// `report_urls` Reporting URLs returned by seller worklet reportResult()
// methods and the winning bidder's reportWin() methods, if any.
//
// `debug_loss_report_urls` URLs to use for reporting loss result to bidders
// and the seller. Empty if no report should be sent.
//
// `debug_win_report_urls` URLs to use for reporting win result to bidders and
// the seller. Empty if no report should be sent.
//
// `interest_groups_that_bid` is a list of the interest groups that made bids
// in the auction. Empty if the auction didn't run to completion.
//
// `errors` are various error messages to be used for debugging. These are too
// sensitive for the renderers to see.
//
// If k-anonymity enforcement is on, `render_url_without_kanon_enforced`
// and `ad_component_urls_without_kanon_enforced` would be set to what the
// winner would be without the enforcement. This may be identical to
// `render_url` and `ad_component_urls`.
//
// If k-anonymity simulation is on, `render_url_with_kanon_simulated` and
// `ad_component_urls_with_kanon_simulated` are what the winner would be if
// k-anonymity was being enforced. This may be identical to `render_url` and
// `ad_component_urls`.
using RunAuctionCallback = base::OnceCallback<void(
AuctionRunner* auction_runner,
bool manually_aborted,
absl::optional<blink::InterestGroupKey> winning_group_id,
absl::optional<GURL> render_url,
std::vector<GURL> ad_component_urls,
std::string winning_group_ad_metadata,
std::vector<GURL> debug_loss_report_urls,
std::vector<GURL> debug_win_report_urls,
std::map<url::Origin, PrivateAggregationRequests>
private_aggregation_requests,
blink::InterestGroupSet interest_groups_that_bid,
base::flat_set<std::string> k_anon_keys_to_join,
std::vector<std::string> errors,
std::unique_ptr<InterestGroupAuctionReporter>
interest_group_auction_reporter)>;
// 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 =
InterestGroupAuction::IsInterestGroupApiAllowedCallback;
// Creates an entire FLEDGE auction. Single-use object.
//
// Arguments:
// `auction_worklet_manager` and `interest_group_manager` must remain valid
// until the AuctionRunner is destroyed.
//
// `auction_config` is the configuration provided by client JavaScript in
// the renderer in order to initiate the auction.
//
// `client_security_state` is the client security state of the frame that
// issued the auction request -- this is used for post-auction interest group
// updates.
//
// `is_interest_group_api_allowed_callback` will be called on all buyer and
// seller origins, and those for which it returns false will not be allowed
// to participate in the auction.
//
// `browser_signals` signals from the browser about the auction that are the
// same for all worklets.
//
// `callback` is invoked on auction completion. It should synchronously
// destroy this AuctionRunner object. `callback` won't be invoked until after
// CreateAndStart() returns.
static std::unique_ptr<AuctionRunner> CreateAndStart(
AuctionWorkletManager* auction_worklet_manager,
InterestGroupManagerImpl* interest_group_manager,
const blink::AuctionConfig& auction_config,
network::mojom::ClientSecurityStatePtr client_security_state,
IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback,
mojo::PendingReceiver<AbortableAdAuction> abort_receiver,
RunAuctionCallback callback);
explicit AuctionRunner(const AuctionRunner&) = delete;
AuctionRunner& operator=(const AuctionRunner&) = delete;
~AuctionRunner() override;
// AbortableAdAuction implementation.
void ResolvedPromiseParam(
blink::mojom::AuctionAdConfigAuctionIdPtr auction,
blink::mojom::AuctionAdConfigField field,
const absl::optional<std::string>& json_value) override;
void Abort() override;
// Fails the auction, invoking `callback_` and prevents any future calls into
// `this` by closing mojo pipes and disposing of weak pointers. The owner must
// be able to safely delete `this` when the callback is invoked. May only be
// invoked if the auction has not yet completed.
//
// `interest_groups_that_bid` is a list of the interest groups that bid in the
// auction.
void FailAuction(bool manually_aborted,
blink::InterestGroupSet interest_groups_that_bid =
blink::InterestGroupSet());
private:
enum class State {
kLoadingGroupsPhase,
kBiddingAndScoringPhase,
kSucceeded,
kFailed,
};
AuctionRunner(
AuctionWorkletManager* auction_worklet_manager,
InterestGroupManagerImpl* interest_group_manager,
auction_worklet::mojom::KAnonymityBidMode kanon_mode,
const blink::AuctionConfig& auction_config,
network::mojom::ClientSecurityStatePtr client_security_state,
IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback,
mojo::PendingReceiver<AbortableAdAuction> abort_receiver,
RunAuctionCallback callback);
// Tells `auction_` to start the loading interest groups phase.
void StartAuction();
// Invoked asynchronously by `auction_` once all interest groups have loaded.
// Fails the auction if `success` is false. Otherwise, starts the bidding and
// scoring phase.
void OnLoadInterestGroupsComplete(bool success);
// Invoked asynchronously by `auction_` once the bidding and scoring phase is
// complete. Either fails the auction (in which case it records the interest
// groups that bid) or starts the reporting phase, depending on the value of
// `success`.
void OnBidsGeneratedAndScored(bool success);
// Invoked asynchronously by `auction_` once the reporting phase has
// completed. Records `interest_groups_that_bid`. If `success` is false, fails
// the auction. Otherwise, records which interest group won the auction and
// collects parameters needed to invoke the auction callback.
void OnReportingPhaseComplete(
blink::InterestGroupSet interest_groups_that_bid,
bool success);
// After an auction completes (success or failure -- wherever `callback_` is
// invoked), updates the set of interest groups that participated in the
// auction.
void UpdateInterestGroupsPostAuction();
const raw_ptr<InterestGroupManagerImpl> interest_group_manager_;
// ClientSecurityState built from the frame that issued the auction request;
// will be used to update interest groups that participated in the auction
// after the auction.
network::mojom::ClientSecurityStatePtr client_security_state_;
// For checking if operations like running auctions, updating interest groups,
// etc. are allowed or not.
IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback_;
mojo::Receiver<blink::mojom::AbortableAdAuction> abort_receiver_;
// Configuration.
// Whether k-anonymity enforcement or simulation (or none) are performed.
const auction_worklet::mojom::KAnonymityBidMode kanon_mode_;
// Use a smart pointer so can pass ownership to InterestGroupAuctionReporter
// without invalidating pointers.
std::unique_ptr<blink::AuctionConfig> owned_auction_config_;
RunAuctionCallback callback_;
// Number of fields in `owned_auction_config_` that are promises; decremented
// as they get resolved.
int promise_fields_in_auction_config_;
InterestGroupAuction auction_;
State state_ = State::kLoadingGroupsPhase;
};
} // namespace content
#endif // CONTENT_BROWSER_INTEREST_GROUP_AUCTION_RUNNER_H_