From ac14ccfbf61e357cf9343105f4f380c1965e325b Mon Sep 17 00:00:00 2001 From: Maks Orlovich Date: Wed, 15 Jan 2025 09:14:35 -0800 Subject: [PATCH] FLEDGE: Handle creative scanning info in TrustedSignalsRequestManager See https://github.com/WICG/turtledove/issues/792#issuecomment-2402992572 for more context. Bug: 383513677 Change-Id: I9df5d3ca4f03e1d57a162e7981bab824331c2460 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6165448 Reviewed-by: mmenke Commit-Queue: Maks Orlovich Cr-Commit-Position: refs/heads/main@{#1406780} --- .../auction_worklet/bidder_worklet.cc | 1 + .../auction_worklet/seller_worklet.cc | 16 +- .../auction_worklet/trusted_signals.cc | 42 ++- .../auction_worklet/trusted_signals.h | 12 +- .../trusted_signals_request_manager.cc | 127 +++---- .../trusted_signals_request_manager.h | 36 +- ...rusted_signals_request_manager_unittest.cc | 332 ++++++++++++++---- .../trusted_signals_unittest.cc | 113 +++++- .../auction_worklet/worklet_test_util.cc | 11 + .../auction_worklet/worklet_test_util.h | 7 + 10 files changed, 522 insertions(+), 175 deletions(-) diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index ff71e8aa73b5dc..d43d64ad8b7405 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc @@ -393,6 +393,7 @@ BidderWorklet::BidderWorklet( /*automatically_send_requests=*/false, top_window_origin, *trusted_bidding_signals_url, experiment_group_id, trusted_bidding_signals_slot_size_param, std::move(public_key), + /*send_creative_scanning_metadata=*/false, v8_helpers_[GetNextThreadIndex()].get()) : nullptr); diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index 22eaed2af8c895..a2020a7f94044b 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc @@ -495,6 +495,7 @@ SellerWorklet::SellerWorklet( /*experiment_group_id=*/experiment_group_id, /*trusted_bidding_signals_slot_size_param=*/std::string(), std::move(public_key), + /*send_creative_scanning_metadata=*/false, v8_helpers_[get_next_thread_index_callback_.Run()].get()) : nullptr); trusted_signals_relation_ = ClassifyTrustedSignals( @@ -2152,14 +2153,22 @@ void SellerWorklet::StartFetchingSignalsForTask( SignalsOriginRelation::kPermittedCrossOriginSignals); score_ad_task->waiting_for_signals_fetch = true; + TrustedSignals::CreativeInfo main_ad; + main_ad.ad_descriptor.url = score_ad_task->browser_signal_render_url; + std::set component_ads; + for (const auto& component_url : + score_ad_task->browser_signal_ad_components) { + TrustedSignals::CreativeInfo component_info; + component_info.ad_descriptor.url = GURL(component_url); + component_ads.insert(std::move(component_info)); + } if (trusted_signals_request_manager_->HasPublicKey()) { DCHECK(base::FeatureList::IsEnabled( blink::features::kFledgeTrustedSignalsKVv2Support)); score_ad_task->trusted_scoring_signals_request = trusted_signals_request_manager_->RequestKVv2ScoringSignals( - score_ad_task->browser_signal_render_url, - score_ad_task->browser_signal_ad_components, + std::move(main_ad), std::move(component_ads), score_ad_task->browser_signal_interest_group_owner, score_ad_task->bidder_joining_origin, base::BindOnce(&SellerWorklet::OnTrustedScoringSignalsDownloaded, @@ -2167,8 +2176,7 @@ void SellerWorklet::StartFetchingSignalsForTask( } else { score_ad_task->trusted_scoring_signals_request = trusted_signals_request_manager_->RequestScoringSignals( - score_ad_task->browser_signal_render_url, - score_ad_task->browser_signal_ad_components, + std::move(main_ad), std::move(component_ads), score_ad_task->auction_ad_config_non_shared_params .max_trusted_scoring_signals_url_length, base::BindOnce(&SellerWorklet::OnTrustedScoringSignalsDownloaded, diff --git a/content/services/auction_worklet/trusted_signals.cc b/content/services/auction_worklet/trusted_signals.cc index 7cba49604b407c..10c51e3bc5033a 100644 --- a/content/services/auction_worklet/trusted_signals.cc +++ b/content/services/auction_worklet/trusted_signals.cc @@ -4,6 +4,7 @@ #include "content/services/auction_worklet/trusted_signals.h" +#include #include #include #include @@ -20,7 +21,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_functions.h" -#include "base/ranges/algorithm.h" #include "base/strings/escape.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" @@ -375,8 +375,11 @@ TrustedSignals::CreativeInfo::CreativeInfo( TrustedSignals::CreativeInfo::~CreativeInfo() = default; TrustedSignals::CreativeInfo::CreativeInfo(CreativeInfo&&) = default; +TrustedSignals::CreativeInfo::CreativeInfo(const CreativeInfo&) = default; TrustedSignals::CreativeInfo& TrustedSignals::CreativeInfo::operator=( CreativeInfo&&) = default; +TrustedSignals::CreativeInfo& TrustedSignals::CreativeInfo::operator=( + const CreativeInfo&) = default; bool TrustedSignals::CreativeInfo::operator<( const TrustedSignals::CreativeInfo& other) const { @@ -478,18 +481,6 @@ GURL TrustedSignals::BuildTrustedScoringSignalsURL( return full_signals_url; } -// static -std::set TrustedSignals::ConvertToCreativeInfoSet( - const std::set& urls) { - std::set result; - for (const auto& url : urls) { - TrustedSignals::CreativeInfo entry; - entry.ad_descriptor.url = GURL(url); - result.insert(std::move(entry)); - } - return result; -} - std::unique_ptr TrustedSignals::LoadBiddingSignals( network::mojom::URLLoaderFactory* url_loader_factory, mojo::PendingRemote @@ -529,19 +520,32 @@ std::unique_ptr TrustedSignals::LoadScoringSignals( network::mojom::URLLoaderFactory* url_loader_factory, mojo::PendingRemote auction_network_events_handler, - std::set render_urls, - std::set ad_component_render_urls, + std::set ads, + std::set ad_components, const std::string& hostname, const GURL& trusted_scoring_signals_url, std::optional experiment_group_id, + bool send_creative_scanning_metadata, scoped_refptr v8_helper, LoadSignalsCallback load_signals_callback) { - DCHECK(!render_urls.empty()); + DCHECK(!ads.empty()); + + auto extract_render_url = [](const CreativeInfo& c) { + return c.ad_descriptor.url.spec(); + }; + + std::set render_urls; + std::ranges::transform(ads, std::inserter(render_urls, render_urls.end()), + extract_render_url); + std::set ad_component_render_urls; + std::ranges::transform( + ad_components, + std::inserter(ad_component_render_urls, ad_component_render_urls.end()), + extract_render_url); GURL full_signals_url = BuildTrustedScoringSignalsURL( - /*send_creative_scanning_metadata=*/false, hostname, - trusted_scoring_signals_url, ConvertToCreativeInfoSet(render_urls), - ConvertToCreativeInfoSet(ad_component_render_urls), experiment_group_id); + send_creative_scanning_metadata, hostname, trusted_scoring_signals_url, + ads, ad_components, experiment_group_id); std::unique_ptr trusted_signals = base::WrapUnique(new TrustedSignals( diff --git a/content/services/auction_worklet/trusted_signals.h b/content/services/auction_worklet/trusted_signals.h index 39e6edd422c8bd..7a58dae46fa63e 100644 --- a/content/services/auction_worklet/trusted_signals.h +++ b/content/services/auction_worklet/trusted_signals.h @@ -165,7 +165,9 @@ class CONTENT_EXPORT TrustedSignals { ~CreativeInfo(); CreativeInfo(CreativeInfo&&); + CreativeInfo(const CreativeInfo&); CreativeInfo& operator=(CreativeInfo&&); + CreativeInfo& operator=(const CreativeInfo&); bool operator<(const CreativeInfo& other) const; @@ -208,11 +210,6 @@ class CONTENT_EXPORT TrustedSignals { const std::set& component_ads, std::optional experiment_group_id); - // This is a transitional method while we're migrating to a new signature - // for loading scoring signals. - static std::set ConvertToCreativeInfoSet( - const std::set& urls); - // Constructs a TrustedSignals for fetching bidding signals, and starts // the fetch. `trusted_bidding_signals_url` must be the base URL (no query // params added). Callback will be invoked asynchronously once the data @@ -245,11 +242,12 @@ class CONTENT_EXPORT TrustedSignals { network::mojom::URLLoaderFactory* url_loader_factory, mojo::PendingRemote auction_network_events_handler, - std::set render_urls, - std::set ad_component_render_urls, + std::set ads, + std::set ad_components, const std::string& hostname, const GURL& trusted_scoring_signals_url, std::optional experiment_group_id, + bool send_creative_scanning_metadata, scoped_refptr v8_helper, LoadSignalsCallback load_signals_callback); diff --git a/content/services/auction_worklet/trusted_signals_request_manager.cc b/content/services/auction_worklet/trusted_signals_request_manager.cc index 68321c5cb1b9b6..faee13edfd6fea 100644 --- a/content/services/auction_worklet/trusted_signals_request_manager.cc +++ b/content/services/auction_worklet/trusted_signals_request_manager.cc @@ -66,8 +66,8 @@ class TrustedSignalsRequestManager::TrustedSignalsUrlBuilder { void Reset() { interest_group_names_.clear(); bidding_signals_keys_.clear(); - render_urls_.clear(); - ad_component_render_urls_.clear(); + ads_.clear(); + ad_components_.clear(); merged_requests_.clear(); length_limit_ = std::numeric_limits::max(); added_first_request_ = false; @@ -91,14 +91,13 @@ class TrustedSignalsRequestManager::TrustedSignalsUrlBuilder { } // Extract the attributes needed to build and create trusted scoring signals. - std::set TakeRenderUrls() { - // We should never try to build a scoring signals URL without any - // render URLs. - DCHECK(render_urls_.size()); - return std::move(render_urls_); + std::set TakeAds() { + // We should never try to build a scoring signals URL without any ads. + DCHECK(ads_.size()); + return std::move(ads_); } - std::set TakeAdComponentRenderUrls() { - return std::move(ad_component_render_urls_); + std::set TakeAdComponents() { + return std::move(ad_components_); } protected: @@ -148,8 +147,8 @@ class TrustedSignalsRequestManager::TrustedSignalsUrlBuilder { std::set bidding_signals_keys_; // Parameters for building a scoring signals URL. - std::set render_urls_; - std::set ad_component_render_urls_; + std::set ads_; + std::set ad_components_; std::set, CompareRequestImpl> merged_requests_; @@ -222,11 +221,13 @@ class TrustedSignalsRequestManager::TrustedScoringSignalsUrlBuilder TrustedScoringSignalsUrlBuilder(std::string hostname, GURL trusted_signals_url, std::optional experiment_group_id, + bool send_creative_scanning_metadata, bool split_fetch) : TrustedSignalsUrlBuilder(std::move(hostname), std::move(trusted_signals_url), experiment_group_id, - split_fetch) {} + split_fetch), + send_creative_scanning_metadata_(send_creative_scanning_metadata) {} TrustedScoringSignalsUrlBuilder& operator=( const TrustedScoringSignalsUrlBuilder&) = delete; @@ -238,37 +239,36 @@ class TrustedSignalsRequestManager::TrustedScoringSignalsUrlBuilder // TrustedSignalsUrlBuilder implementation. GURL Build() override { return TrustedSignals::BuildTrustedScoringSignalsURL( - /*send_creative_scanning_metadata=*/false, hostname_, - trusted_signals_url_, - TrustedSignals::ConvertToCreativeInfoSet(render_urls_), - TrustedSignals::ConvertToCreativeInfoSet(ad_component_render_urls_), - experiment_group_id_); + send_creative_scanning_metadata_, hostname_, trusted_signals_url_, ads_, + ad_components_, experiment_group_id_); } bool TryToAddRequest(RequestImpl* request) override { // Keep track of iterators of newly inserted values so they can easily be // removed if the URL gets too big. - auto added_render_url = - render_urls_.insert(request->render_url_.value().spec()); - std::vector::iterator> inserted_component_urls; - for (const std::string& render_url : *request->ad_component_render_urls_) { - auto inserted = ad_component_render_urls_.insert(render_url); + auto added_creative = ads_.emplace(*request->ad_); + std::vector::iterator> + inserted_components; + for (const auto& component : request->ad_components_) { + auto inserted = ad_components_.insert(component); if (inserted.second) { - inserted_component_urls.push_back(inserted.first); + inserted_components.push_back(inserted.first); } } if (!AddRequestIfUrlNotTooBig(request)) { - if (added_render_url.second) { - render_urls_.erase(added_render_url.first); + if (added_creative.second) { + ads_.erase(added_creative.first); } - for (const std::set::iterator& component_url : - inserted_component_urls) { - ad_component_render_urls_.erase(component_url); + for (const auto& component_iter : inserted_components) { + ad_components_.erase(component_iter); } return false; } return true; } + + private: + const bool send_creative_scanning_metadata_; }; TrustedSignalsRequestManager::TrustedSignalsRequestManager( @@ -282,10 +282,12 @@ TrustedSignalsRequestManager::TrustedSignalsRequestManager( std::optional experiment_group_id, const std::string& trusted_bidding_signals_slot_size_param, mojom::TrustedSignalsPublicKeyPtr public_key, + bool send_creative_scanning_metadata, AuctionV8Helper* v8_helper) : type_(type), url_loader_factory_(url_loader_factory), automatically_send_requests_(automatically_send_requests), + send_creative_scanning_metadata_(send_creative_scanning_metadata), top_level_origin_(top_level_origin), trusted_signals_url_(trusted_signals_url), experiment_group_id_(experiment_group_id), @@ -327,16 +329,14 @@ TrustedSignalsRequestManager::RequestBiddingSignals( std::unique_ptr TrustedSignalsRequestManager::RequestScoringSignals( - const GURL& render_url, - const std::vector& ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, int32_t max_trusted_scoring_signals_url_length, LoadSignalsCallback load_signals_callback) { DCHECK_EQ(Type::kScoringSignals, type_); auto request = std::make_unique( - this, render_url, - std::set(ad_component_render_urls.begin(), - ad_component_render_urls.end()), + this, std::move(ad), std::move(ad_components), max_trusted_scoring_signals_url_length, std::move(load_signals_callback)); QueueRequest(request.get()); return request; @@ -363,19 +363,16 @@ TrustedSignalsRequestManager::RequestKVv2BiddingSignals( std::unique_ptr TrustedSignalsRequestManager::RequestKVv2ScoringSignals( - const GURL& render_url, - const std::vector& ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, const url::Origin& bidder_owner_origin, const url::Origin& bidder_joining_origin, LoadSignalsCallback load_signals_callback) { DCHECK_EQ(Type::kScoringSignals, type_); auto request = std::make_unique( - this, render_url, - std::set(ad_component_render_urls.begin(), - ad_component_render_urls.end()), - bidder_owner_origin, bidder_joining_origin, - std::move(load_signals_callback)); + this, std::move(ad), std::move(ad_components), bidder_owner_origin, + bidder_joining_origin, std::move(load_signals_callback)); QueueRequest(request.get()); return request; } @@ -411,9 +408,9 @@ void TrustedSignalsRequestManager::IssueRequests( /*auction_network_events_handler=*/ CreateNewAuctionNetworkEventsHandlerRemote( auction_network_events_handler_), - url_builder.TakeRenderUrls(), url_builder.TakeAdComponentRenderUrls(), + url_builder.TakeAds(), url_builder.TakeAdComponents(), top_level_origin_.host(), trusted_signals_url_, experiment_group_id_, - v8_helper_, + send_creative_scanning_metadata_, v8_helper_, base::BindOnce(&TrustedSignalsRequestManager::OnSignalsLoaded, base::Unretained(this), batched_request)); } @@ -497,21 +494,25 @@ void TrustedSignalsRequestManager::StartBatchedTrustedSignalsRequest() { public_key_->Clone())); for (auto& request : batched_request->requests) { - CHECK(request->render_url_.has_value()); - CHECK(request->ad_component_render_urls_.has_value()); + CHECK(request->ad_.has_value()); CHECK(request->bidder_owner_origin_.has_value()); CHECK(request->bidder_joining_origin_.has_value()); + std::set local_ad_component_render_urls; + for (const auto& component : request->ad_components_) { + local_ad_component_render_urls.emplace( + component.ad_descriptor.url.spec()); + } + request->SetKVv2IsolationIndex(helper_builder->AddTrustedSignalsRequest( - request->render_url_.value(), - request->ad_component_render_urls_.value(), + request->ad_->ad_descriptor.url, local_ad_component_render_urls, request->bidder_owner_origin_.value(), request->bidder_joining_origin_.value())); - render_urls.emplace(request->render_url_->spec()); - ad_component_render_urls.insert( - request->ad_component_render_urls_->begin(), - request->ad_component_render_urls_->end()); - request->render_url_.reset(); + render_urls.emplace(request->ad_->ad_descriptor.url.spec()); + ad_component_render_urls.insert(local_ad_component_render_urls.begin(), + local_ad_component_render_urls.end()); + request->ad_.reset(); + request->ad_components_.clear(); request->batched_request_ = batched_request; } @@ -543,7 +544,7 @@ void TrustedSignalsRequestManager::StartBatchedTrustedSignalsRequest() { } else { url_builder = std::make_unique( top_level_origin_.host(), trusted_signals_url_, experiment_group_id_, - split_fetch); + send_creative_scanning_metadata_, split_fetch); } for (auto& request : queued_requests_) { @@ -592,12 +593,12 @@ TrustedSignalsRequestManager::RequestImpl::RequestImpl( TrustedSignalsRequestManager::RequestImpl::RequestImpl( TrustedSignalsRequestManager* trusted_signals_request_manager, - const GURL& render_url, - std::set ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, int32_t max_trusted_scoring_signals_url_length, LoadSignalsCallback load_signals_callback) - : render_url_(render_url), - ad_component_render_urls_(std::move(ad_component_render_urls)), + : ad_(std::move(ad)), + ad_components_(std::move(ad_components)), load_signals_callback_(std::move(load_signals_callback)), trusted_signals_request_manager_(trusted_signals_request_manager) { DCHECK(max_trusted_scoring_signals_url_length >= 0); @@ -625,13 +626,13 @@ TrustedSignalsRequestManager::RequestImpl::RequestImpl( TrustedSignalsRequestManager::RequestImpl::RequestImpl( TrustedSignalsRequestManager* trusted_signals_request_manager, - const GURL& render_url, - std::set ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, const url::Origin& bidder_owner_origin, const url::Origin& bidder_joining_origin, LoadSignalsCallback load_signals_callback) - : render_url_(render_url), - ad_component_render_urls_(std::move(ad_component_render_urls)), + : ad_(std::move(ad)), + ad_components_(std::move(ad_components)), bidder_owner_origin_(bidder_owner_origin), bidder_joining_origin_(bidder_joining_origin), load_signals_callback_(std::move(load_signals_callback)), @@ -659,12 +660,12 @@ bool TrustedSignalsRequestManager::CompareRequestImpl::operator()( const RequestImpl* r2) const { if (r1->interest_group_name_.has_value() && r2->interest_group_name_.has_value()) { - DCHECK(!r1->render_url_.has_value() && !r2->render_url_.has_value()); + DCHECK(!r1->ad_.has_value() && !r2->ad_.has_value()); return std::tie(r1->interest_group_name_, r1) < std::tie(r2->interest_group_name_, r2); } else { - DCHECK(r1->render_url_.has_value() && r2->render_url_.has_value()); - return std::tie(r1->render_url_, r1) < std::tie(r2->render_url_, r2); + DCHECK(r1->ad_.has_value() && r2->ad_.has_value()); + return std::tie(r1->ad_, r1) < std::tie(r2->ad_, r2); } } diff --git a/content/services/auction_worklet/trusted_signals_request_manager.h b/content/services/auction_worklet/trusted_signals_request_manager.h index 5e30f56466031a..ad69da8c06f489 100644 --- a/content/services/auction_worklet/trusted_signals_request_manager.h +++ b/content/services/auction_worklet/trusted_signals_request_manager.h @@ -97,6 +97,12 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { // non-null, it will trigger the KVv2 call flow and be used during the message // encryption and decryption process. // + // For sellers using KVv1 protocol, `send_creative_scanning_metadata` controls + // whether additional fields like creative_scanning_metadata, size and owner + // info are sent with trusted scoring requests. If this is off, this + // information should not be included in the passed in + // TrustedSignals::CreativeInfo. + // // TODO(crbug.com/40810962): Investigate improving the // `automatically_send_requests` logic. TrustedSignalsRequestManager( @@ -110,6 +116,7 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { std::optional experiment_group_id, const std::string& trusted_bidding_signals_slot_size_param, mojom::TrustedSignalsPublicKeyPtr public_key, + bool send_creative_scanning_metadata, AuctionV8Helper* v8_helper); explicit TrustedSignalsRequestManager(const TrustedSignalsRequestManager&) = @@ -136,8 +143,8 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { // the format matches the one accepted by ScoringSignals::Result, which // minimizes conversions. std::unique_ptr RequestScoringSignals( - const GURL& render_url, - const std::vector& ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, int32_t max_trusted_scoring_signals_url_length, LoadSignalsCallback load_signals_callback); @@ -155,8 +162,8 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { // support. Requires `bidder_owner_origin` and `bidder_joining_origin` instead // of `max_trusted_scoring_signals_url_length`. std::unique_ptr RequestKVv2ScoringSignals( - const GURL& render_url, - const std::vector& ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, const url::Origin& bidder_owner_origin, const url::Origin& bidder_joining_origin, LoadSignalsCallback load_signals_callback); @@ -185,8 +192,8 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { // Constructor for the BYOS version of trusted scoring signals, which builds // a GET request with a limit set by max_trusted_scoring_signals_url_length. RequestImpl(TrustedSignalsRequestManager* trusted_signals_request_manager, - const GURL& render_url, - std::set ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, int32_t max_trusted_scoring_signals_url_length, LoadSignalsCallback load_signals_callback); @@ -202,8 +209,8 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { // Constructor for trusted scoring signals with KVv2 support, which builds a // POST request. RequestImpl(TrustedSignalsRequestManager* trusted_signals_request_manager, - const GURL& render_url, - std::set ad_component_render_urls, + TrustedSignals::CreativeInfo ad, + std::set ad_components, const url::Origin& bidder_owner_origin, const url::Origin& bidder_joining_origin, LoadSignalsCallback load_signals_callback); @@ -225,13 +232,11 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { std::optional joining_origin_; std::optional execution_mode_; - // Used for requests for scoring signals. `render_url_` must be non-null - // and non-empty for scoring signals requests, and - // `ad_component_render_urls_` non-null. Both must be null for bidding - // signals requests. - std::optional render_url_; - // Stored as a std::set for simpler - std::optional> ad_component_render_urls_; + // Used for requests for scoring signals. `ad_` must be non-null for + // scoring signals requests. `ad_` and `ad_components_` must be nullopt and + // empty respectively for bidding signals requests. + std::optional ad_; + std::set ad_components_; std::optional bidder_owner_origin_; std::optional bidder_joining_origin_; @@ -315,6 +320,7 @@ class CONTENT_EXPORT TrustedSignalsRequestManager { const Type type_; const raw_ptr url_loader_factory_; const bool automatically_send_requests_; + const bool send_creative_scanning_metadata_; const url::Origin top_level_origin_; const GURL trusted_signals_url_; const std::optional experiment_group_id_; diff --git a/content/services/auction_worklet/trusted_signals_request_manager_unittest.cc b/content/services/auction_worklet/trusted_signals_request_manager_unittest.cc index 700175c1c6e867..058fa7f8896438 100644 --- a/content/services/auction_worklet/trusted_signals_request_manager_unittest.cc +++ b/content/services/auction_worklet/trusted_signals_request_manager_unittest.cc @@ -25,6 +25,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "base/test/values_test_util.h" #include "components/cbor/reader.h" #include "components/cbor/values.h" #include "components/cbor/writer.h" @@ -258,6 +259,17 @@ mojom::TrustedSignalsPublicKeyPtr CreateDefaultPublicKey() { kKeyId); } +std::set ToCreativeInfo( + const std::vector& render_urls) { + return CreateCreativeInfoSet(render_urls); +} + +TrustedSignals::CreativeInfo ToCreativeInfo(const GURL& url) { + TrustedSignals::CreativeInfo ad; + ad.ad_descriptor.url = url; + return ad; +} + // Callback for loading signals that stores the result and runs a closure to // exit a message loop. void LoadSignalsCallback(scoped_refptr* results_out, @@ -281,7 +293,8 @@ void NeverInvokedLoadSignalsCallback( class TrustedSignalsRequestManagerTest : public testing::Test { public: explicit TrustedSignalsRequestManagerTest( - mojom::TrustedSignalsPublicKeyPtr public_key = nullptr) + mojom::TrustedSignalsPublicKeyPtr public_key = nullptr, + bool send_creative_scanning_metadata = false) : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), v8_helper_( AuctionV8Helper::Create(AuctionV8Helper::CreateTaskRunner())), @@ -296,6 +309,7 @@ class TrustedSignalsRequestManagerTest : public testing::Test { /*experiment_group_id=*/std::nullopt, "trusted_bidding_signals_slot_size_param=foo", std::move(public_key), + /*send_creative_scanning_metadata=*/false, v8_helper_.get()), scoring_request_manager_( TrustedSignalsRequestManager::Type::kScoringSignals, @@ -308,6 +322,7 @@ class TrustedSignalsRequestManagerTest : public testing::Test { /*experiment_group_id=*/std::nullopt, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, + send_creative_scanning_metadata, v8_helper_.get()) {} ~TrustedSignalsRequestManagerTest() override { @@ -370,7 +385,7 @@ class TrustedSignalsRequestManagerTest : public testing::Test { scoped_refptr signals; base::RunLoop run_loop; auto request = scoring_request_manager_.RequestScoringSignals( - render_url, ad_component_render_urls, + ToCreativeInfo(render_url), ToCreativeInfo(ad_component_render_urls), max_trusted_scoring_signals_url_length, base::BindOnce(&LoadSignalsCallback, &signals, &error_msg_, run_loop.QuitClosure())); @@ -579,8 +594,8 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsBatchedRequestError) { scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - GURL("https://foo.test/"), - /*ad_component_render_urls=*/{}, + ToCreativeInfo(GURL("https://foo.test/")), + /*ad_components=*/{}, /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -589,8 +604,8 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsBatchedRequestError) { scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - GURL("https://bar.test/"), - /*ad_component_render_urls=*/{}, + ToCreativeInfo(GURL("https://bar.test/")), + /*ad_components=*/{}, /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -931,7 +946,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -942,7 +957,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -1083,7 +1098,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsBatchedRequests) { scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -1092,7 +1107,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsBatchedRequests) { scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -1101,7 +1116,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsBatchedRequests) { scoped_refptr signals3; std::optional error_msg3; auto request3 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl3, kAdComponentRenderUrls3, + ToCreativeInfo(kRenderUrl3), ToCreativeInfo(kAdComponentRenderUrls3), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals3, &error_msg3, run_loop3.QuitClosure())); @@ -1313,7 +1328,7 @@ TEST_F(TrustedSignalsRequestManagerTest, AutomaticallySendRequestsEnabled) { url::Origin::Create(GURL(kTopLevelOrigin)), trusted_signals_url_, /*experiment_group_id=*/std::nullopt, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); // Create one Request. base::RunLoop run_loop1; @@ -1397,7 +1412,7 @@ TEST_F(TrustedSignalsRequestManagerTest, url::Origin::Create(GURL(kTopLevelOrigin)), trusted_signals_url_, /*experiment_group_id=*/std::nullopt, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); // Create one Request. auto request1 = bidding_request_manager.RequestBiddingSignals( @@ -1459,7 +1474,7 @@ TEST_F(TrustedSignalsRequestManagerTest, url::Origin::Create(GURL(kTopLevelOrigin)), trusted_signals_url_, /*experiment_group_id=*/std::nullopt, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); // Create one Request. auto request1 = bidding_request_manager.RequestBiddingSignals( @@ -1514,7 +1529,7 @@ TEST_F(TrustedSignalsRequestManagerTest, BiddingExperimentGroupIds) { url::Origin::Create(GURL(kTopLevelOrigin)), trusted_signals_url_, /*experiment_group_id=*/934u, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); AddBidderJsonResponse( &url_loader_factory_, GURL("https://url.test/" @@ -1557,7 +1572,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringExperimentGroupIds) { url::Origin::Create(GURL(kTopLevelOrigin)), trusted_signals_url_, /*experiment_group_id=*/344u, /*trusted_bidding_signals_slot_size_param=*/"", /*public_key=*/nullptr, - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); AddJsonResponse(&url_loader_factory_, GURL("https://url.test/?hostname=publisher" @@ -1570,7 +1585,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringExperimentGroupIds) { scoped_refptr signals; std::optional error_msg; auto request1 = scoring_request_manager.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals, &error_msg, run_loop.QuitClosure())); @@ -1879,7 +1894,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsJointBatchedRequests) { std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -1888,7 +1903,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsJointBatchedRequests) { scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/1000, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -2037,7 +2052,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsSplitBatchedRequests) { std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/200, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -2046,7 +2061,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsSplitBatchedRequests) { scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/200, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -2220,7 +2235,7 @@ TEST_F(TrustedSignalsRequestManagerTest, std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -2229,7 +2244,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/1000, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -2238,7 +2253,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals3; std::optional error_msg3; auto request3 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl3, kAdComponentRenderUrls3, + ToCreativeInfo(kRenderUrl3), ToCreativeInfo(kAdComponentRenderUrls3), /*max_trusted_scoring_signals_url_length=*/200, base::BindOnce(&LoadSignalsCallback, &signals3, &error_msg3, run_loop3.QuitClosure())); @@ -2427,7 +2442,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals3; std::optional error_msg3; auto request3 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl3, kAdComponentRenderUrls3, + ToCreativeInfo(kRenderUrl3), ToCreativeInfo(kAdComponentRenderUrls3), /*max_trusted_scoring_signals_url_length=*/208, base::BindOnce(&LoadSignalsCallback, &signals3, &error_msg3, run_loop3.QuitClosure())); @@ -2437,7 +2452,7 @@ TEST_F(TrustedSignalsRequestManagerTest, std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), /*max_trusted_scoring_signals_url_length=*/0, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -2446,7 +2461,7 @@ TEST_F(TrustedSignalsRequestManagerTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), /*max_trusted_scoring_signals_url_length=*/208, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -2577,7 +2592,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsIdenticalRequests) { std::optional error_msg1; auto request1 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl, {}, + ToCreativeInfo(kRenderUrl), {}, /*max_trusted_scoring_signals_url_length=*/50, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -2586,7 +2601,7 @@ TEST_F(TrustedSignalsRequestManagerTest, ScoringSignalsIdenticalRequests) { scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_.RequestScoringSignals( - kRenderUrl, {}, + ToCreativeInfo(kRenderUrl), {}, /*max_trusted_scoring_signals_url_length=*/50, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -2706,7 +2721,7 @@ class TrustedSignalsRequestManagerKVv2EmbeddedTest : public testing::Test { url::Origin::Create(GURL(kTopLevelOrigin)), TrustedBiddingSignalsUrl(), /*experiment_group_id=*/std::nullopt, "trusted_bidding_signals_slot_size_param=foo", CreateDefaultPublicKey(), - v8_helper_.get()); + /*send_creative_scanning_metadata=*/false, v8_helper_.get()); scoring_request_manager_ = std::make_unique( TrustedSignalsRequestManager::Type::kScoringSignals, @@ -2717,7 +2732,8 @@ class TrustedSignalsRequestManagerKVv2EmbeddedTest : public testing::Test { url::Origin::Create(GURL(kTopLevelOrigin)), TrustedScoringSignalsUrl(), /*experiment_group_id=*/std::nullopt, /*trusted_bidding_signals_slot_size_param=*/"", - CreateDefaultPublicKey(), v8_helper_.get()); + CreateDefaultPublicKey(), /*send_creative_scanning_metadata=*/false, + v8_helper_.get()); } ~TrustedSignalsRequestManagerKVv2EmbeddedTest() override { @@ -2768,8 +2784,8 @@ class TrustedSignalsRequestManagerKVv2EmbeddedTest : public testing::Test { scoped_refptr signals; base::RunLoop run_loop; auto request = scoring_request_manager_->RequestKVv2ScoringSignals( - render_url, ad_component_render_urls, bidder_owner_origin, - bidder_joining_origin, + ToCreativeInfo(render_url), ToCreativeInfo(ad_component_render_urls), + bidder_owner_origin, bidder_joining_origin, base::BindOnce(&LoadSignalsCallback, &signals, &error_msg_, run_loop.QuitClosure())); scoring_request_manager_->StartBatchedTrustedSignalsRequest(); @@ -3447,9 +3463,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://bar.test/"), - {"https://barsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://bar.test/")), + ToCreativeInfo(std::vector{"https://barsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -3457,9 +3474,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://baz.test/"), - {"https://bazsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://baz.test/")), + ToCreativeInfo(std::vector{"https://bazsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -3487,9 +3505,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://bar.test/"), - {"https://barsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://bar.test/")), + ToCreativeInfo(std::vector{"https://barsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -3497,9 +3516,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://baz.test/"), - {"https://bazsub.test/", "https://foosub.test/"}, owner_origin_b_, - joining_origin_b_, + ToCreativeInfo(GURL("https://baz.test/")), + ToCreativeInfo(std::vector{"https://bazsub.test/", + "https://foosub.test/"}), + owner_origin_b_, joining_origin_b_, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -3507,8 +3527,9 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals3; std::optional error_msg3; auto request3 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://qux.test/"), - {"https://quxsub.test/", "https://foosub.test/"}, + ToCreativeInfo(GURL("https://qux.test/")), + ToCreativeInfo(std::vector{"https://quxsub.test/", + "https://foosub.test/"}), url::Origin::Create(GURL("https://owner-c.test")), url::Origin::Create(GURL("https://origin-c.test")), base::BindOnce(&LoadSignalsCallback, &signals3, &error_msg3, @@ -3545,7 +3566,8 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_->RequestKVv2ScoringSignals( - kRenderUrl1, kAdComponentRenderUrls1, owner_origin_a_, joining_origin_a_, + ToCreativeInfo(kRenderUrl1), ToCreativeInfo(kAdComponentRenderUrls1), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -3553,7 +3575,8 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_->RequestKVv2ScoringSignals( - kRenderUrl2, kAdComponentRenderUrls2, owner_origin_b_, joining_origin_b_, + ToCreativeInfo(kRenderUrl2), ToCreativeInfo(kAdComponentRenderUrls2), + owner_origin_b_, joining_origin_b_, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -3592,9 +3615,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://bar.test/"), - {"https://barsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://bar.test/")), + ToCreativeInfo(std::vector{"https://barsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -3602,9 +3626,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://baz.test/"), - {"https://bazsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://baz.test/")), + ToCreativeInfo(std::vector{"https://bazsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -3674,9 +3699,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals1; std::optional error_msg1; auto request1 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://bar.test/"), - {"https://barsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://bar.test/")), + ToCreativeInfo(std::vector{"https://barsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, run_loop1.QuitClosure())); @@ -3686,9 +3712,10 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, scoped_refptr signals2; std::optional error_msg2; auto request2 = scoring_request_manager_->RequestKVv2ScoringSignals( - GURL("https://baz.test/"), - {"https://bazsub.test/", "https://foosub.test/"}, owner_origin_a_, - joining_origin_a_, + ToCreativeInfo(GURL("https://baz.test/")), + ToCreativeInfo(std::vector{"https://bazsub.test/", + "https://foosub.test/"}), + owner_origin_a_, joining_origin_a_, base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, run_loop2.QuitClosure())); @@ -3721,5 +3748,188 @@ TEST_F(TrustedSignalsRequestManagerKVv2EmbeddedTest, kAdComponentRenderUrls2)); } +class TrustedSignalsRequestManagerCreativeScanTest + : public TrustedSignalsRequestManagerTest { + public: + // This always turns KVv2 off, since there is currently no creative scanning + // with it. + TrustedSignalsRequestManagerCreativeScanTest() + : TrustedSignalsRequestManagerTest( + /*public_key=*/nullptr, + /*send_creative_scanning_metadata=*/true) { + ads_.emplace_back( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foo.test"), + blink::AdSize(100, blink::AdSize::LengthUnit::kPixels, 50, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"s1", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b1.test"))); + + ads_.emplace_back( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foo.test"), + blink::AdSize(100, blink::AdSize::LengthUnit::kPixels, 50, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"s2", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test"))); + + ads_.emplace_back( + /*ad_descriptor=*/blink::AdDescriptor(GURL("https://bar.test")), + /*creative_scanning_metadata=*/"s3", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test"))); + + ad_components_.emplace_back( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foosub.test"), + blink::AdSize(30, blink::AdSize::LengthUnit::kPixels, 16, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"c1", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b1.test"))); + + ad_components_.emplace_back( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://barsub.test"), + blink::AdSize(60, blink::AdSize::LengthUnit::kPixels, 32, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"c2", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test"))); + } + + protected: + std::vector ads_; + std::vector ad_components_; + url::Origin joining_origin_{url::Origin::Create(GURL(kJoiningOriginA))}; +}; + +TEST_F(TrustedSignalsRequestManagerCreativeScanTest, ManyRequests) { + for (const bool split : {false, true}) { + SCOPED_TRACE(split); + url_loader_factory_.ClearResponses(); + base::RunLoop run_loop1; + scoped_refptr signals1; + std::optional error_msg1; + int max_trusted_scoring_signals_url_length = + split ? 1 : std::numeric_limits::max(); + auto request1 = scoring_request_manager_.RequestScoringSignals( + ads_[0], {ad_components_[0]}, max_trusted_scoring_signals_url_length, + base::BindOnce(&LoadSignalsCallback, &signals1, &error_msg1, + run_loop1.QuitClosure())); + + base::RunLoop run_loop2; + scoped_refptr signals2; + std::optional error_msg2; + auto request2 = scoring_request_manager_.RequestScoringSignals( + ads_[1], {ad_components_[1]}, max_trusted_scoring_signals_url_length, + base::BindOnce(&LoadSignalsCallback, &signals2, &error_msg2, + run_loop2.QuitClosure())); + + base::RunLoop run_loop3; + scoped_refptr signals3; + std::optional error_msg3; + auto request3 = scoring_request_manager_.RequestScoringSignals( + ads_[2], {ad_components_[0], ad_components_[1]}, + max_trusted_scoring_signals_url_length, + base::BindOnce(&LoadSignalsCallback, &signals3, &error_msg3, + run_loop3.QuitClosure())); + + if (split) { + GURL url1( + "https://url.test/?hostname=publisher&" + "renderUrls=https%3A%2F%2Ffoo.test%2F" + "&adComponentRenderUrls=https%3A%2F%2Ffoosub.test%2F" + "&adCreativeScanningMetadata=s1" + "&adComponentCreativeScanningMetadata=c1" + "&adSizes=100px,50px" + "&adComponentSizes=30px,16px" + "&adBuyer=https%3A%2F%2Fb1.test" + "&adComponentBuyer=https%3A%2F%2Fb1.test"); + AddJsonResponse(&url_loader_factory_, url1, kBaseScoringJson); + + GURL url2( + "https://url.test/?hostname=publisher&" + "renderUrls=https%3A%2F%2Ffoo.test%2F" + "&adComponentRenderUrls=https%3A%2F%2Fbarsub.test%2F" + "&adCreativeScanningMetadata=s2" + "&adComponentCreativeScanningMetadata=c2" + "&adSizes=100px,50px" + "&adComponentSizes=60px,32px" + "&adBuyer=https%3A%2F%2Fb2.test" + "&adComponentBuyer=https%3A%2F%2Fb2.test"); + AddJsonResponse(&url_loader_factory_, url2, kBaseScoringJson); + + GURL url3( + "https://url.test/?hostname=publisher&" + "renderUrls=https%3A%2F%2Fbar.test%2F" + "&adComponentRenderUrls=https%3A%2F%2Fbarsub.test%2F," + "https%3A%2F%2Ffoosub.test%2F" + "&adCreativeScanningMetadata=s3" + "&adComponentCreativeScanningMetadata=c2,c1" + "&adSizes=," + "&adComponentSizes=60px,32px,30px,16px" + "&adBuyer=https%3A%2F%2Fb2.test" + "&adComponentBuyer=https%3A%2F%2Fb2.test,https%3A%2F%2Fb1.test"); + AddJsonResponse(&url_loader_factory_, url3, kBaseScoringJson); + } else { + GURL url( + "https://url.test/?hostname=publisher&" + "renderUrls=https%3A%2F%2Fbar.test%2F,https%3A%2F%2Ffoo.test%2F," + "https%3A%2F%2Ffoo.test%2F" + "&adComponentRenderUrls=https%3A%2F%2Fbarsub.test%2F," + "https%3A%2F%2Ffoosub.test%2F" + "&adCreativeScanningMetadata=s3,s1,s2" + "&adComponentCreativeScanningMetadata=c2,c1" + "&adSizes=,,100px,50px,100px,50px" + "&adComponentSizes=60px,32px,30px,16px" + "&adBuyer=https%3A%2F%2Fb2.test,https%3A%2F%2Fb1.test," + "https%3A%2F%2Fb2.test" + "&adComponentBuyer=https%3A%2F%2Fb2.test,https%3A%2F%2Fb1.test"); + AddJsonResponse(&url_loader_factory_, url, kBaseScoringJson); + } + scoring_request_manager_.StartBatchedTrustedSignalsRequest(); + + run_loop1.Run(); + EXPECT_FALSE(error_msg1) << *error_msg1; + ASSERT_TRUE(signals1); + EXPECT_THAT( + ExtractScoringSignals(signals1.get(), ads_[0].ad_descriptor.url, + {ad_components_[0].ad_descriptor.url.spec()}), + base::test::IsJson(R"({ + "renderURL":{"https://foo.test/":1}, + "renderUrl":{"https://foo.test/":1}, + "adComponentRenderURLs":{"https://foosub.test/":2}, + "adComponentRenderUrls":{"https://foosub.test/":2} + })")); + + run_loop2.Run(); + EXPECT_FALSE(error_msg2) << *error_msg2; + ASSERT_TRUE(signals2); + EXPECT_THAT( + ExtractScoringSignals(signals2.get(), ads_[1].ad_descriptor.url, + {ad_components_[1].ad_descriptor.url.spec()}), + base::test::IsJson(R"({ + "renderURL":{"https://foo.test/":1}, + "renderUrl":{"https://foo.test/":1}, + "adComponentRenderURLs":{"https://barsub.test/":[3]}, + "adComponentRenderUrls":{"https://barsub.test/":[3]} + })")); + + run_loop3.Run(); + EXPECT_FALSE(error_msg3) << *error_msg3; + ASSERT_TRUE(signals3); + EXPECT_THAT( + ExtractScoringSignals(signals3.get(), ads_[2].ad_descriptor.url, + {ad_components_[0].ad_descriptor.url.spec(), + ad_components_[1].ad_descriptor.url.spec()}), + base::test::IsJson(R"({ + "renderURL":{"https://bar.test/":[2]}, + "renderUrl":{"https://bar.test/":[2]}, + "adComponentRenderURLs":{"https://foosub.test/":2, + "https://barsub.test/":[3]}, + "adComponentRenderUrls":{"https://foosub.test/":2, + "https://barsub.test/":[3]} + })")); + } +} + } // namespace } // namespace auction_worklet diff --git a/content/services/auction_worklet/trusted_signals_unittest.cc b/content/services/auction_worklet/trusted_signals_unittest.cc index 2f8898ead332a6..31eceb66f803bf 100644 --- a/content/services/auction_worklet/trusted_signals_unittest.cc +++ b/content/services/auction_worklet/trusted_signals_unittest.cc @@ -20,6 +20,7 @@ #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "base/test/values_test_util.h" #include "content/common/features.h" #include "content/services/auction_worklet/auction_v8_helper.h" #include "content/services/auction_worklet/worklet_test_util.h" @@ -239,13 +240,26 @@ class TrustedSignalsTest : public testing::Test { std::set ad_component_render_urls, const std::string& hostname, std::optional experiment_group_id) { - CHECK(!load_signals_run_loop_); + auto ads = CreateCreativeInfoSet( + std::vector(render_urls.begin(), render_urls.end())); + auto ad_components = CreateCreativeInfoSet(std::vector( + ad_component_render_urls.begin(), ad_component_render_urls.end())); + return FetchScoringSignals(std::move(ads), std::move(ad_components), + hostname, experiment_group_id); + } + scoped_refptr FetchScoringSignals( + std::set ads, + std::set ad_components, + const std::string& hostname, + std::optional experiment_group_id, + bool send_creative_scanning_metadata = false) { + CHECK(!load_signals_run_loop_); DCHECK(!load_signals_result_); auto scoring_signals = TrustedSignals::LoadScoringSignals( &url_loader_factory_, auction_network_events_handler_.CreateRemote(), - std::move(render_urls), std::move(ad_component_render_urls), hostname, - base_url_, experiment_group_id, v8_helper_, + std::move(ads), std::move(ad_components), hostname, base_url_, + experiment_group_id, send_creative_scanning_metadata, v8_helper_, base::BindOnce(&TrustedSignalsTest::LoadSignalsCallback, base::Unretained(this))); WaitForLoadComplete(); @@ -1152,9 +1166,10 @@ TEST_F(TrustedSignalsTest, ScoringSignalsDeleteBeforeCallback) { base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); auto scoring_signals = TrustedSignals::LoadScoringSignals( &url_loader_factory_, auction_network_events_handler_.CreateRemote(), - /*render_urls=*/{"http://foo.test/"}, - /*ad_component_render_urls=*/{}, "publisher", base_url_, - /*experiment_group_id=*/std::nullopt, v8_helper_, + CreateCreativeInfoSet({"http://foo.test/"}), + /*ad_components=*/{}, "publisher", base_url_, + /*experiment_group_id=*/std::nullopt, + /*send_creative_scanning_metadata=*/false, v8_helper_, base::BindOnce([](scoped_refptr result, std::optional error_msg) { ADD_FAILURE() << "Callback should not be invoked since loader deleted"; @@ -1589,5 +1604,91 @@ TEST_F(TrustedSignalsTest, "&adBuyer=https%3A%2F%2Fb1.test,https%3A%2F%2Fb2.test", result); } + +TEST_F(TrustedSignalsTest, ScoringSignalsCreativeScanning) { + std::set ads; + ads.insert(TrustedSignals::CreativeInfo( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foo.test"), + blink::AdSize(100, blink::AdSize::LengthUnit::kPixels, 50, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"s1", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b1.test")))); + + ads.insert(TrustedSignals::CreativeInfo( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foo.test"), + blink::AdSize(100, blink::AdSize::LengthUnit::kPixels, 50, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"s2", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test")))); + + ads.insert(TrustedSignals::CreativeInfo( + /*ad_descriptor=*/blink::AdDescriptor(GURL("https://bar.test")), + /*creative_scanning_metadata=*/"s3", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test")))); + + std::set ad_components; + ad_components.insert(TrustedSignals::CreativeInfo( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://foosub.test"), + blink::AdSize(30, blink::AdSize::LengthUnit::kPixels, 16, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"c1", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b1.test")))); + + ad_components.insert(TrustedSignals::CreativeInfo( + /*ad_descriptor=*/blink::AdDescriptor( + GURL("https://barsub.test"), + blink::AdSize(60, blink::AdSize::LengthUnit::kPixels, 32, + blink::AdSize::LengthUnit::kPixels)), + /*creative_scanning_metadata=*/"c2", + /*interest_group_owner=*/url::Origin::Create(GURL("https://b2.test")))); + + GURL response_url( + "https://url.test/?hostname=publisher&" + "renderUrls=https%3A%2F%2Fbar.test%2F,https%3A%2F%2Ffoo.test%2F," + "https%3A%2F%2Ffoo.test%2F" + "&adComponentRenderUrls=https%3A%2F%2Fbarsub.test%2F," + "https%3A%2F%2Ffoosub.test%2F" + "&adCreativeScanningMetadata=s3,s1,s2" + "&adComponentCreativeScanningMetadata=c2,c1" + "&adSizes=,,100px,50px,100px,50px" + "&adComponentSizes=60px,32px,30px,16px" + "&adBuyer=https%3A%2F%2Fb2.test,https%3A%2F%2Fb1.test," + "https%3A%2F%2Fb2.test" + "&adComponentBuyer=https%3A%2F%2Fb2.test,https%3A%2F%2Fb1.test"); + + AddJsonResponse(&url_loader_factory_, response_url, kBaseScoringJson); + + scoped_refptr signals = + FetchScoringSignals(std::move(ads), std::move(ad_components), kHostname, + /*experiment_group_id=*/std::nullopt, + /*send_creative_scanning_metadata=*/true); + ASSERT_TRUE(signals); + + EXPECT_THAT(ExtractScoringSignals( + signals.get(), + /*render_url=*/GURL("https://foo.test/"), + /*ad_component_render_urls=*/{"https://foosub.test/"}), + base::test::IsJson(R"({ + "renderURL":{"https://foo.test/":1}, + "renderUrl":{"https://foo.test/":1}, + "adComponentRenderURLs":{"https://foosub.test/":2}, + "adComponentRenderUrls":{"https://foosub.test/":2} + })")); + + EXPECT_THAT(ExtractScoringSignals( + signals.get(), + /*render_url=*/GURL("https://bar.test/"), + /*ad_component_render_urls=*/{"https://barsub.test/"}), + base::test::IsJson(R"({ + "renderURL":{"https://bar.test/":[2]}, + "renderUrl":{"https://bar.test/":[2]}, + "adComponentRenderURLs":{"https://barsub.test/":[3]}, + "adComponentRenderUrls":{"https://barsub.test/":[3]} + })")); +} + } // namespace } // namespace auction_worklet diff --git a/content/services/auction_worklet/worklet_test_util.cc b/content/services/auction_worklet/worklet_test_util.cc index c2f0bf022156b0..01e49c9f5aa955 100644 --- a/content/services/auction_worklet/worklet_test_util.cc +++ b/content/services/auction_worklet/worklet_test_util.cc @@ -273,4 +273,15 @@ TestAuctionNetworkEventsHandler::GetObservedRequests() { return observed_requests_; } +std::set CreateCreativeInfoSet( + const std::vector& urls) { + std::set result; + for (const auto& url : urls) { + TrustedSignals::CreativeInfo entry; + entry.ad_descriptor.url = GURL(url); + result.insert(std::move(entry)); + } + return result; +} + } // namespace auction_worklet diff --git a/content/services/auction_worklet/worklet_test_util.h b/content/services/auction_worklet/worklet_test_util.h index 90fa489c033e6d..8c66ffc902fe80 100644 --- a/content/services/auction_worklet/worklet_test_util.h +++ b/content/services/auction_worklet/worklet_test_util.h @@ -6,12 +6,14 @@ #define CONTENT_SERVICES_AUCTION_WORKLET_WORKLET_TEST_UTIL_H_ #include +#include #include #include #include "base/types/optional_ref.h" #include "content/services/auction_worklet/public/mojom/auction_network_events_handler.mojom.h" #include "content/services/auction_worklet/public/mojom/auction_shared_storage_host.mojom.h" +#include "content/services/auction_worklet/trusted_signals.h" #include "net/http/http_status_code.h" #include "services/network/public/mojom/shared_storage.mojom-forward.h" #include "services/network/test/test_url_loader_factory.h" @@ -184,6 +186,11 @@ class TestAuctionNetworkEventsHandler auction_network_events_handlers_; }; +// A helper to make testing common cases in trusted seller signals easier, by +// construsting the larger type it needs from simpler string input. +std::set CreateCreativeInfoSet( + const std::vector& urls); + } // namespace auction_worklet #endif // CONTENT_SERVICES_AUCTION_WORKLET_WORKLET_TEST_UTIL_H_