0

FLEDGE: extend information reported about auctions to devtools

A new, frame-specific interestGroupAuctionEvent is added, which reports auction configuration, structure of component auctions, and names each auction (including component ones) with a unique ID.

The existing interestGroupAccessed events that take place as part of auctions now specify which auction they are part of, and provide information on bid values. Bids taking place in top-level auctions are now also reported.

Bug: 1516642
Fuchsia-Binary-Size: Size increase is unavoidable.
Change-Id: I6109f2e3d60d52421b5be445f19e5faa74ab9e3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5153907
Commit-Queue: Maks Orlovich <morlovich@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Ayu Ishii <ayui@chromium.org>
Reviewed-by: Russ Hamilton <behamilton@google.com>
Cr-Commit-Position: refs/heads/main@{#1249552}
This commit is contained in:
Maks Orlovich
2024-01-19 21:49:46 +00:00
committed by Chromium LUCI CQ
parent 533d6ba7c5
commit a7d97ed824
23 changed files with 811 additions and 285 deletions

@@ -1198,6 +1198,7 @@ source_set("browser") {
"interest_group/debuggable_auction_worklet.h",
"interest_group/debuggable_auction_worklet_tracker.cc",
"interest_group/debuggable_auction_worklet_tracker.h",
"interest_group/devtools_enums.h",
"interest_group/header_direct_from_seller_signals.cc",
"interest_group/header_direct_from_seller_signals.h",
"interest_group/interest_group_auction.cc",

@@ -29,6 +29,7 @@
#include "content/browser/devtools/protocol/page_handler.h"
#include "content/browser/devtools/protocol/preload_handler.h"
#include "content/browser/devtools/protocol/security_handler.h"
#include "content/browser/devtools/protocol/storage_handler.h"
#include "content/browser/devtools/protocol/target_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
@@ -1526,6 +1527,36 @@ void OnAuctionWorkletNetworkRequestComplete(
status);
}
bool NeedInterestGroupAuctionEvents(int frame_tree_node_id) {
FrameTreeNode* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id);
if (!ftn) {
return false;
}
DevToolsAgentHostImpl* agent_host = RenderFrameDevToolsAgentHost::GetFor(ftn);
if (!agent_host) {
return false;
}
for (auto* storage : protocol::StorageHandler::ForAgentHost(agent_host)) {
if (storage->interest_group_auction_tracking_enabled()) {
return true;
}
}
return false;
}
void OnInterestGroupAuctionEventOccurred(
int frame_tree_node_id,
base::Time event_time,
InterestGroupAuctionEventType type,
const std::string& unique_auction_id,
base::optional_ref<const std::string> parent_auction_id,
const base::Value::Dict& auction_config) {
DispatchToAgents(
frame_tree_node_id,
&protocol::StorageHandler::NotifyInterestGroupAuctionEventOccurred,
event_time, type, unique_auction_id, parent_auction_id, auction_config);
}
void OnNavigationRequestWillBeSent(
const NavigationRequest& navigation_request) {
// Note this intentionally deviates from the usual instrumentation signal

@@ -12,8 +12,10 @@
#include <optional>
#include <vector>
#include "base/values.h"
#include "content/browser/devtools/devtools_device_request_prompt_info.h"
#include "content/browser/devtools/devtools_throttle_handle.h"
#include "content/browser/interest_group/devtools_enums.h"
#include "content/browser/preloading/prefetch/prefetch_status.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/renderer_host/back_forward_cache_impl.h"
@@ -229,6 +231,16 @@ void OnAuctionWorkletNetworkRequestComplete(
const std::string& request_id,
const network::URLLoaderCompletionStatus& status);
bool NeedInterestGroupAuctionEvents(int frame_tree_node_id);
void OnInterestGroupAuctionEventOccurred(
int frame_tree_node_id,
base::Time event_time,
content::InterestGroupAuctionEventType type,
const std::string& unique_auction_id,
base::optional_ref<const std::string> parent_auction_id,
const base::Value::Dict& auction_config);
bool ShouldBypassCSP(const NavigationRequest& nav_request);
void ApplyNetworkOverridesForDownload(

@@ -450,6 +450,12 @@ StorageHandler::~StorageHandler() {
DCHECK(!indexed_db_observer_);
}
// static
std::vector<StorageHandler*> StorageHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
return host->HandlersByName<StorageHandler>(Storage::Metainfo::domainName);
}
void StorageHandler::Wire(UberDispatcher* dispatcher) {
frontend_ = std::make_unique<Storage::Frontend>(dispatcher->channel());
Storage::Dispatcher::wire(dispatcher, this);
@@ -1016,10 +1022,14 @@ void StorageHandler::ClearTrustTokens(
}
void StorageHandler::OnInterestGroupAccessed(
const base::Time& access_time,
base::optional_ref<const std::string> auction_id,
base::Time access_time,
InterestGroupManagerImpl::InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) {
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
using AccessType =
InterestGroupManagerImpl::InterestGroupObserver::AccessType;
@@ -1052,9 +1062,22 @@ void StorageHandler::OnInterestGroupAccessed(
case AccessType::kClear:
type_enum = Storage::InterestGroupAccessTypeEnum::Clear;
break;
case AccessType::kTopLevelBid:
type_enum = Storage::InterestGroupAccessTypeEnum::TopLevelBid;
break;
case AccessType::kTopLevelAdditionalBid:
type_enum = Storage::InterestGroupAccessTypeEnum::TopLevelAdditionalBid;
break;
};
frontend_->InterestGroupAccessed(access_time.InSecondsFSinceUnixEpoch(),
type_enum, owner_origin.Serialize(), name);
frontend_->InterestGroupAccessed(
access_time.InSecondsFSinceUnixEpoch(), type_enum,
owner_origin.Serialize(), name,
component_seller_origin.has_value()
? Maybe<String>(component_seller_origin->Serialize())
: Maybe<String>(),
bid.has_value() ? Maybe<double>(*bid) : Maybe<double>(),
bid_currency.has_value() ? Maybe<String>(*bid_currency) : Maybe<String>(),
auction_id.has_value() ? Maybe<String>(*auction_id) : Maybe<String>());
}
namespace {
@@ -1188,6 +1211,11 @@ Response StorageHandler::SetInterestGroupTracking(bool enable) {
return Response::Success();
}
Response StorageHandler::SetInterestGroupAuctionTracking(bool enable) {
interest_group_auction_tracking_enabled_ = enable;
return Response::Success();
}
namespace {
void SendSharedStorageMetadata(
@@ -2135,5 +2163,30 @@ Response StorageHandler::SetAttributionReportingTracking(bool enable) {
return Response::Success();
}
void StorageHandler::NotifyInterestGroupAuctionEventOccurred(
base::Time event_time,
content::InterestGroupAuctionEventType type,
const std::string& unique_auction_id,
base::optional_ref<const std::string> parent_auction_id,
const base::Value::Dict& auction_config) {
if (!interest_group_auction_tracking_enabled_) {
return;
}
std::string type_enum;
switch (type) {
case content::InterestGroupAuctionEventType::kStarted:
type_enum = Storage::InterestGroupAuctionEventTypeEnum::Started;
break;
case content::InterestGroupAuctionEventType::kConfigResolved:
type_enum = Storage::InterestGroupAuctionEventTypeEnum::ConfigResolved;
break;
};
frontend_->InterestGroupAuctionEventOccurred(
event_time.InSecondsFSinceUnixEpoch(), type_enum, unique_auction_id,
parent_auction_id.has_value() ? Maybe<String>(*parent_auction_id)
: Maybe<String>(),
std::make_unique<base::Value::Dict>(auction_config.Clone()));
}
} // namespace protocol
} // namespace content

@@ -10,10 +10,12 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/types/optional_ref.h"
#include "components/services/storage/shared_storage/shared_storage_manager.h"
#include "content/browser/attribution_reporting/attribution_observer.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/storage.h"
#include "content/browser/interest_group/devtools_enums.h"
#include "content/browser/interest_group/interest_group_manager_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
@@ -43,12 +45,18 @@ class StorageHandler
~StorageHandler() override;
static std::vector<StorageHandler*> ForAgentHost(DevToolsAgentHostImpl* host);
// content::protocol::DevToolsDomainHandler
void Wire(UberDispatcher* dispatcher) override;
void SetRenderer(int process_host_id,
RenderFrameHostImpl* frame_host) override;
Response Disable() override;
bool interest_group_auction_tracking_enabled() const {
return interest_group_auction_tracking_enabled_;
}
// content::protocol::storage::Backend
Response GetStorageKeyForFrame(const std::string& frame_id,
std::string* serialized_storage_key) override;
@@ -109,6 +117,7 @@ class StorageHandler
const std::string& name,
std::unique_ptr<GetInterestGroupDetailsCallback> callback) override;
Response SetInterestGroupTracking(bool enable) override;
Response SetInterestGroupAuctionTracking(bool enable) override;
void GetSharedStorageMetadata(
const std::string& owner_origin_string,
@@ -147,6 +156,13 @@ class StorageHandler
override;
Response SetAttributionReportingTracking(bool enable) override;
void NotifyInterestGroupAuctionEventOccurred(
base::Time event_time,
content::InterestGroupAuctionEventType type,
const std::string& unique_auction_id,
base::optional_ref<const std::string> parent_auction_id,
const base::Value::Dict& auction_config);
private:
// See definition for lifetime information.
class CacheStorageObserver;
@@ -167,10 +183,14 @@ class StorageHandler
// content::InterestGroupManagerImpl::InterestGroupObserver
void OnInterestGroupAccessed(
const base::Time& accessTime,
base::optional_ref<const std::string> auction_id,
base::Time access_time,
InterestGroupManagerImpl::InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) override;
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) override;
// AttributionObserver
void OnSourceHandled(
@@ -219,6 +239,8 @@ class StorageHandler
std::unique_ptr<storage::QuotaOverrideHandle> quota_override_handle_;
bool client_is_trusted_;
bool interest_group_auction_tracking_enabled_ = false;
base::ScopedObservation<AttributionManager, AttributionObserver>
attribution_observation_{this};

@@ -830,12 +830,13 @@ class AdAuctionServiceImplTest : public RenderViewHostTestHarness {
scoped_refptr<StorageInterestGroups> interest_groups;
base::RunLoop run_loop;
manager_->GetInterestGroupsForOwner(
owner, base::BindLambdaForTesting(
[&run_loop, &interest_groups](
scoped_refptr<StorageInterestGroups> groups) {
interest_groups = std::move(groups);
run_loop.Quit();
}));
/*devtools_auction_id=*/std::nullopt, owner,
base::BindLambdaForTesting(
[&run_loop,
&interest_groups](scoped_refptr<StorageInterestGroups> groups) {
interest_groups = std::move(groups);
run_loop.Quit();
}));
run_loop.Run();
return interest_groups;
}

@@ -0,0 +1,14 @@
// Copyright 2024 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_DEVTOOLS_ENUMS_H_
#define CONTENT_BROWSER_INTEREST_GROUP_DEVTOOLS_ENUMS_H_
namespace content {
enum class InterestGroupAuctionEventType { kStarted, kConfigResolved };
} // namespace content
#endif // CONTENT_BROWSER_INTEREST_GROUP_DEVTOOLS_ENUMS_H_

@@ -39,10 +39,12 @@
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/token.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_id_helper.h"
#include "base/types/optional_ref.h"
#include "base/uuid.h"
#include "content/browser/devtools/devtools_instrumentation.h"
#include "content/browser/interest_group/ad_auction_page_data.h"
#include "content/browser/interest_group/additional_bid_result.h"
#include "content/browser/interest_group/additional_bids_util.h"
@@ -2128,7 +2130,8 @@ InterestGroupAuction::InterestGroupAuction(
base::RepeatingCallback<
void(const PrivateAggregationRequests& private_aggregation_requests)>
maybe_log_private_aggregation_web_features_callback)
: trace_id_(base::trace_event::GetNextGlobalTraceId()),
: devtools_auction_id_(base::Token::CreateRandom().ToString()),
trace_id_(base::trace_event::GetNextGlobalTraceId()),
kanon_mode_(kanon_mode),
auction_worklet_manager_(auction_worklet_manager),
auction_nonce_manager_(auction_nonce_manager),
@@ -2150,6 +2153,17 @@ InterestGroupAuction::InterestGroupAuction(
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("fledge", "auction", *trace_id_,
"decision_logic_url",
config_->decision_logic_url);
int frame_tree_node_id = auction_worklet_manager_->GetFrameTreeNodeID();
if (devtools_instrumentation::NeedInterestGroupAuctionEvents(
frame_tree_node_id)) {
devtools_instrumentation::OnInterestGroupAuctionEventOccurred(
frame_tree_node_id, auction_start_time_,
InterestGroupAuctionEventType::kStarted, devtools_auction_id_,
parent_ ? base::optional_ref<const std::string>(
parent->devtools_auction_id_)
: base::optional_ref<const std::string>(),
config_->SerializeForDevtools());
}
uint32_t child_pos = 0;
for (const auto& component_auction_config :
@@ -2296,8 +2310,9 @@ void InterestGroupAuction::StartLoadInterestGroupsPhase(
continue;
}
interest_group_manager_->GetInterestGroupsForOwner(
buyer, base::BindOnce(&InterestGroupAuction::OnInterestGroupRead,
weak_ptr_factory_.GetWeakPtr()));
devtools_auction_id_, buyer,
base::BindOnce(&InterestGroupAuction::OnInterestGroupRead,
weak_ptr_factory_.GetWeakPtr()));
++num_pending_loads_;
}
}
@@ -2717,10 +2732,10 @@ InterestGroupAuction::CreateReporter(
interest_group_manager_, auction_worklet_manager_, browser_context,
private_aggregation_manager,
maybe_log_private_aggregation_web_features_callback_,
std::move(auction_config), main_frame_origin, frame_origin,
std::move(client_security_state), std::move(url_loader_factory),
kanon_mode_, bid_is_kanon, std::move(winning_bid_info),
std::move(top_level_seller_winning_bid_info),
std::move(auction_config), devtools_auction_id_, main_frame_origin,
frame_origin, std::move(client_security_state),
std::move(url_loader_factory), kanon_mode_, bid_is_kanon,
std::move(winning_bid_info), std::move(top_level_seller_winning_bid_info),
std::move(component_seller_winning_bid_info),
std::move(interest_groups_that_bid), std::move(debug_win_report_urls),
std::move(debug_loss_report_urls), GetKAnonKeysToJoin(),
@@ -2745,6 +2760,18 @@ void InterestGroupAuction::NotifyConfigPromisesResolved() {
auction_metrics_recorder_->OnConfigPromisesResolved();
int frame_tree_node_id = auction_worklet_manager_->GetFrameTreeNodeID();
if (devtools_instrumentation::NeedInterestGroupAuctionEvents(
frame_tree_node_id)) {
devtools_instrumentation::OnInterestGroupAuctionEventOccurred(
frame_tree_node_id, base::Time::Now(),
InterestGroupAuctionEventType::kConfigResolved, devtools_auction_id_,
parent_ ? base::optional_ref<const std::string>(
parent_->devtools_auction_id_)
: base::optional_ref<const std::string>(),
config_->SerializeForDevtools());
}
// If we haven't started the bidding and scoring phase, we will just handle
// this information at its start; setting `config_promises_resolved_` is
// enough both for us and the BuyerHelper. If we are after the phase, that
@@ -2925,9 +2952,14 @@ void InterestGroupAuction::GetInterestGroupsThatBidAndReportBidCounts(
saved_response_->bidding_groups.end());
for (const auto& ig_bid : interest_groups) {
interest_group_manager_->NotifyInterestGroupAccessed(
devtools_auction_id_,
InterestGroupManagerImpl::InterestGroupObserver::
InterestGroupObserver::kBid,
ig_bid.owner, ig_bid.name);
ig_bid.owner, ig_bid.name,
/*component_seller_origin=*/std::nullopt,
// Don't know individual bid values of a server-side auction, just
// that the IGs participated.
/*bid=*/std::nullopt, /*bid_currency=*/std::nullopt);
}
return;
}
@@ -4148,18 +4180,32 @@ void InterestGroupAuction::ScoreBidIfReady(std::unique_ptr<Bid> bid) {
any_bid_made_ = true;
// TODO(https://crbug.com/1516642): Report component auctions participating
// in top-level auction, as well as k-anon re-runs.
if (component_auctions_.empty() &&
IsBidRoleUsedForWinner(kanon_mode_, bid->bid_role)) {
// TODO(https://crbug.com/1516642): Report k-anon re-runs.
if (IsBidRoleUsedForWinner(kanon_mode_, bid->bid_role)) {
InterestGroupManagerImpl::InterestGroupObserver::AccessType event_type =
InterestGroupManagerImpl::InterestGroupObserver::kBid;
if (!component_auctions_.empty()) {
event_type =
bid->bid_state->additional_bid_buyer
? InterestGroupManagerImpl::InterestGroupObserver::
kTopLevelAdditionalBid
: InterestGroupManagerImpl::InterestGroupObserver::kTopLevelBid;
} else if (bid->bid_state->additional_bid_buyer) {
event_type =
InterestGroupManagerImpl::InterestGroupObserver::kAdditionalBid;
}
interest_group_manager_->NotifyInterestGroupAccessed(
bid->bid_state->additional_bid_buyer
? InterestGroupManagerImpl::InterestGroupObserver::
InterestGroupObserver::kAdditionalBid
: InterestGroupManagerImpl::InterestGroupObserver::
InterestGroupObserver::kBid,
devtools_auction_id_, event_type,
bid->bid_state->bidder->interest_group.owner,
bid->bid_state->bidder->interest_group.name);
bid->bid_state->bidder->interest_group.name,
component_auctions_.empty() ? base::optional_ref<const url::Origin>()
: base::optional_ref<const url::Origin>(
bid->auction->config_->seller),
bid->bid,
bid->bid_currency
? base::optional_ref(bid->bid_currency->currency_code())
: base::optional_ref<const std::string>());
}
// If seller worklet hasn't been received yet, or configuration is still

@@ -1192,6 +1192,10 @@ class CONTENT_EXPORT InterestGroupAuction
static data_decoder::DataDecoder* GetDataDecoder(
base::WeakPtr<InterestGroupAuction> instance);
// For associating various events with a particular auction. Note that
// component auctions have their own.
const std::string devtools_auction_id_;
// 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

@@ -163,6 +163,7 @@ InterestGroupAuctionReporter::InterestGroupAuctionReporter(
LogPrivateAggregationRequestsCallback
log_private_aggregation_requests_callback,
std::unique_ptr<blink::AuctionConfig> auction_config,
const std::string& devtools_auction_id,
const url::Origin& main_frame_origin,
const url::Origin& frame_origin,
network::mojom::ClientSecurityStatePtr client_security_state,
@@ -186,6 +187,7 @@ InterestGroupAuctionReporter::InterestGroupAuctionReporter(
log_private_aggregation_requests_callback_(
std::move(log_private_aggregation_requests_callback)),
auction_config_(std::move(auction_config)),
devtools_auction_id_(devtools_auction_id),
main_frame_origin_(main_frame_origin),
frame_origin_(frame_origin),
client_security_state_(std::move(client_security_state)),
@@ -1004,18 +1006,23 @@ void InterestGroupAuctionReporter::OnNavigateToWinningAd(
const blink::InterestGroup& winning_group =
winning_bid_info_.storage_interest_group->interest_group;
if (!winning_bid_info_.provided_as_additional_bid) {
InterestGroupManagerImpl::InterestGroupObserver::AccessType win_type =
InterestGroupManagerImpl::InterestGroupObserver::kWin;
if (winning_bid_info_.provided_as_additional_bid) {
win_type =
InterestGroupManagerImpl::InterestGroupObserver::kAdditionalBidWin;
} else {
interest_group_manager_->RecordInterestGroupWin(
blink::InterestGroupKey(winning_group.owner, winning_group.name),
winning_bid_info_.ad_metadata);
interest_group_manager_->NotifyInterestGroupAccessed(
InterestGroupManagerImpl::InterestGroupObserver::kWin,
winning_group.owner, winning_group.name);
} else {
interest_group_manager_->NotifyInterestGroupAccessed(
InterestGroupManagerImpl::InterestGroupObserver::kAdditionalBidWin,
winning_group.owner, winning_group.name);
}
interest_group_manager_->NotifyInterestGroupAccessed(
devtools_auction_id_, win_type, winning_group.owner, winning_group.name,
component_seller_winning_bid_info_.has_value()
? base::optional_ref<const url::Origin>(
component_seller_winning_bid_info_->auction_config->seller)
: base::optional_ref<const url::Origin>(),
/*bid=*/std::nullopt, /*bid_currency=*/std::nullopt);
interest_group_manager_->RegisterAdKeysAsJoined(
std::move(k_anon_keys_to_join_));

@@ -246,6 +246,7 @@ class CONTENT_EXPORT InterestGroupAuctionReporter {
LogPrivateAggregationRequestsCallback
log_private_aggregation_requests_callback,
std::unique_ptr<blink::AuctionConfig> auction_config,
const std::string& devtools_auction_id,
const url::Origin& main_frame_origin,
const url::Origin& frame_origin,
network::mojom::ClientSecurityStatePtr client_security_state,
@@ -480,6 +481,7 @@ class CONTENT_EXPORT InterestGroupAuctionReporter {
// SellerWinningBidInfo, it points to an AuctionConfig contained within it.
const std::unique_ptr<blink::AuctionConfig> auction_config_;
const std::optional<std::string> devtools_auction_id_;
const url::Origin main_frame_origin_;
const url::Origin frame_origin_;
const network::mojom::ClientSecurityStatePtr client_security_state_;

@@ -249,8 +249,8 @@ class InterestGroupAuctionReporterTest
&private_aggregation_manager_,
private_aggregation_manager_
.GetLogPrivateAggregationRequestsCallback(),
std::move(auction_config_), kTopFrameOrigin, kFrameOrigin,
frame_client_security_state_.Clone(),
std::move(auction_config_), kDevtoolsAuctionId, kTopFrameOrigin,
kFrameOrigin, frame_client_security_state_.Clone(),
dummy_report_shared_url_loader_factory_,
auction_worklet::mojom::KAnonymityBidMode::kNone, false,
std::move(winning_bid_info_), std::move(seller_winning_bid_info_),
@@ -467,6 +467,7 @@ class InterestGroupAuctionReporterTest
EventReportingAttestationBrowserClient browser_client_;
ScopedContentBrowserClientSetting browser_client_setting_{&browser_client_};
const std::string kDevtoolsAuctionId = "123-456";
const url::Origin kTopFrameOrigin =
url::Origin::Create(GURL("https://top_frame_origin.test/"));
const url::Origin kFrameOrigin =

@@ -1129,7 +1129,7 @@ class InterestGroupBrowserTest : public ContentBrowserTest {
scoped_refptr<StorageInterestGroups> result;
base::RunLoop run_loop;
manager_->GetInterestGroupsForOwner(
owner,
/*devtools_auction_id=*/std::nullopt, owner,
base::BindLambdaForTesting(
[&result, &run_loop](scoped_refptr<StorageInterestGroups> groups) {
result = std::move(groups);
@@ -2393,10 +2393,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
/*joining_url=*/embedded_https_test_server().GetURL("b.test", "/echo"));
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin_a, kName1},
{TestInterestGroupObserver::kJoin, test_origin_a, kName2},
{TestInterestGroupObserver::kJoin, test_origin_a, kName3},
{TestInterestGroupObserver::kJoin, test_origin_a, kName4}});
{{"global", TestInterestGroupObserver::kJoin, test_origin_a, kName1},
{"global", TestInterestGroupObserver::kJoin, test_origin_a, kName2},
{"global", TestInterestGroupObserver::kJoin, test_origin_a, kName3},
{"global", TestInterestGroupObserver::kJoin, test_origin_a, kName4}});
EXPECT_EQ(kSuccess, ClearOriginJoinedInterestGroups(
test_origin_a, /*groups_to_keep=*/{{kName2}}));
@@ -2404,8 +2404,8 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
// kName2 and kName4 should not be cleared. Don't check exact order, as
// there's no guarantee about the order groups will be listed in.
WaitForAccessObserved(
{{TestInterestGroupObserver::kClear, test_origin_a, kName1},
{TestInterestGroupObserver::kClear, test_origin_a, kName3}});
{{"global", TestInterestGroupObserver::kClear, test_origin_a, kName1},
{"global", TestInterestGroupObserver::kClear, test_origin_a, kName3}});
}
// Can't join or leave interest groups from http://localhost, even though it's
@@ -3199,7 +3199,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
})())",
test_origin, url)));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
});
auto storage_groups = GetInterestGroupsForOwner(test_origin);
ASSERT_EQ(storage_groups->size(), 1u);
@@ -3253,7 +3253,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, JoinInterestGroupLifetimeMs) {
})())",
test_origin)));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
});
auto storage_groups = GetInterestGroupsForOwner(test_origin);
ASSERT_EQ(storage_groups->size(), 1u);
@@ -3286,7 +3286,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
})())",
test_origin)));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
});
auto storage_groups = GetInterestGroupsForOwner(test_origin);
ASSERT_EQ(storage_groups->size(), 1u);
@@ -3745,7 +3745,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
})())",
origin)));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, origin, "cars"},
});
scoped_refptr<StorageInterestGroups> groups =
GetInterestGroupsForOwner(origin);
@@ -4690,7 +4690,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
? kAdditionalBidKeySloppyBase64
: kAdditionalBidKeyBase64)));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, origin, "cars"},
});
scoped_refptr<StorageInterestGroups> groups =
GetInterestGroupsForOwner(origin);
@@ -7871,7 +7871,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
embedded_https_test_server().GetURL(
"/interest_group/decision_logic.js")));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin_a, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin_a, "cars"},
});
}
@@ -7940,11 +7940,11 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
embedded_https_test_server().GetURL(
"/interest_group/bidding_logic_stop_bidding_after_win.js")));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, disabled_origin, "candy"},
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, disabled_origin, "candy"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
}
@@ -8494,10 +8494,10 @@ IN_PROC_BROWSER_TEST_F(
"a.test", "/interest_group/decision_logic.js")),
ad_url);
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
}
IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionCancel) {
@@ -9406,10 +9406,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// Leaving the winning interest group should succeed. Do it by calling
// Javascript directly instead of loading a page that does this
@@ -9420,7 +9420,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// The leave should be observed.
WaitForAccessObserved(
{{TestInterestGroupObserver::kLeave, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kLeave, test_origin, "cars"}});
EXPECT_TRUE(GetAllInterestGroups().empty());
}
@@ -9463,10 +9463,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// Leaving the winning interest group should fail. Do it by calling Javascript
// directly instead of loading a page that does this to avoid races with
@@ -9529,10 +9529,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// Leaving the winning interest group from the nested iframe should succeed.
// Do it by calling Javascript directly instead of loading a page that does
@@ -9544,7 +9544,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// The leave should be observed.
WaitForAccessObserved(
{{TestInterestGroupObserver::kLeave, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kLeave, test_origin, "cars"}});
EXPECT_TRUE(GetAllInterestGroups().empty());
}
@@ -9597,10 +9597,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// Leaving the winning interest group from the nested iframe should fail.
// Do it by calling Javascript directly instead of loading a page that does
@@ -9705,13 +9705,13 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kJoin, test_origin, "trucks"},
{TestInterestGroupObserver::kLoaded, test_origin, "trucks"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "trucks"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "trucks"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "trucks"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 2.0},
{"1", TestInterestGroupObserver::kBid, test_origin, "trucks", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
// Try to leave the winning interest group, which should fail, since the ad is
@@ -9742,10 +9742,10 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
// attempt, as updating the data is potentially racy with the navigation
// committing, so the leave event could appear out of order.
WaitForAccessObserved(
{{TestInterestGroupObserver::kLoaded, test_origin, "trucks"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "trucks"},
{TestInterestGroupObserver::kWin, test_origin, "trucks"}});
{{"2", TestInterestGroupObserver::kLoaded, test_origin, "trucks"},
{"2", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"2", TestInterestGroupObserver::kBid, test_origin, "trucks", 1.0},
{"2", TestInterestGroupObserver::kWin, test_origin, "trucks"}});
// Try to leave the winning interest group, which should succeed this time. Do
// it by calling Javascript directly instead of loading a page that does this
@@ -9753,7 +9753,7 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
EXPECT_EQ(nullptr, EvalJs(GetFencedFrameRenderFrameHost(rfh2),
"navigator.leaveAdInterestGroup()"));
WaitForAccessObserved(
{{TestInterestGroupObserver::kLeave, test_origin, "trucks"}});
{{"global", TestInterestGroupObserver::kLeave, test_origin, "trucks"}});
// Only the "truck" interest group should have been left.
auto groups = GetAllInterestGroups();
@@ -9764,8 +9764,6 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
// Runs ad auction with fenced frames enabled. The auction should succeed and
// be loaded in a fenced frame. The displayed ad leaves the interest group
// from a nested iframe.
//
// TODO(crbug.com/1320438): Re-enable the test.
IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
RunAdAuctionWithWinnerNestedLeaveGroup) {
URLLoaderMonitor url_loader_monitor;
@@ -9816,10 +9814,10 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
// InterestGroupAccessObserver should see the join and auction.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// Leave the interest group and wait to observe the event. Do this after the
// above WaitForAccessObserved() call, as leaving is racy with recording the
@@ -9829,7 +9827,7 @@ perBuyerSignals: {$1: {even: 'more', x: 4.5}}
->current_frame_host(),
"navigator.leaveAdInterestGroup()"));
WaitForAccessObserved(
{{TestInterestGroupObserver::kLeave, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kLeave, test_origin, "cars"}});
// The ad should have left the interest group when the page was shown.
EXPECT_EQ(0u, GetAllInterestGroups().size());
@@ -9940,7 +9938,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest,
// InterestGroupAccessObserver should see the join.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"}});
// The ad should not have left the interest group when the page was shown.
EXPECT_EQ(1u, GetAllInterestGroups().size());
@@ -10030,10 +10028,10 @@ function reportResult(
seller_signals_url, bidder_origin));
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, bidder_origin, "cars"},
{TestInterestGroupObserver::kLoaded, bidder_origin, "cars"},
{TestInterestGroupObserver::kBid, bidder_origin, "cars"},
{TestInterestGroupObserver::kWin, bidder_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, bidder_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, bidder_origin, "cars"},
});
// Reporting urls should be fetched after an auction succeeded.
@@ -10091,10 +10089,10 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad_url);
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
// Wait for the component to load.
@@ -10382,14 +10380,14 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionAllGroupsLimited) {
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad1_url);
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
}
@@ -10495,22 +10493,22 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionOneGroupLimited) {
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad1_url);
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{TestInterestGroupObserver::kJoin, test_origin2, "cars"},
{TestInterestGroupObserver::kJoin, test_origin2, "bikes"},
{TestInterestGroupObserver::kJoin, test_origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin2, "bikes"},
{TestInterestGroupObserver::kLoaded, test_origin2, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin2, "bikes"},
{TestInterestGroupObserver::kBid, test_origin2, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "bikes"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "bikes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 2.0},
{"1", TestInterestGroupObserver::kBid, test_origin2, "bikes", 1.0},
{"1", TestInterestGroupObserver::kBid, test_origin2, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
}
@@ -10617,23 +10615,23 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad1_url);
WaitForAccessObserved({
{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{TestInterestGroupObserver::kJoin, test_origin2, "cars"},
{TestInterestGroupObserver::kJoin, test_origin2, "bikes"},
{TestInterestGroupObserver::kJoin, test_origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, test_origin2, "bikes"},
{TestInterestGroupObserver::kLoaded, test_origin2, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin2, "bikes"},
{TestInterestGroupObserver::kBid, test_origin2, "cars"},
{TestInterestGroupObserver::kBid, test_origin2, "shoes"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "bikes"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "shoes"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "bikes"},
{"global", TestInterestGroupObserver::kJoin, test_origin2, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "bikes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "bikes"},
{"1", TestInterestGroupObserver::kLoaded, test_origin2, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 2.0},
{"1", TestInterestGroupObserver::kBid, test_origin2, "bikes", 1.0},
{"1", TestInterestGroupObserver::kBid, test_origin2, "cars", 1.0},
{"1", TestInterestGroupObserver::kBid, test_origin2, "shoes", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
});
}
@@ -10782,19 +10780,20 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionMultipleAuctions) {
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad1_url);
// Wait for interest groups to be updated. Interest groups are updated
// during/after commit, so this test is potentially racy without this.
WaitForAccessObserved({{TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, origin, "cars"},
{TestInterestGroupObserver::kBid, origin, "cars"},
{TestInterestGroupObserver::kBid, origin2, "shoes"},
{TestInterestGroupObserver::kWin, origin, "cars"}});
WaitForAccessObserved(
{{"1", TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{"1", TestInterestGroupObserver::kLoaded, origin, "cars"},
{"1", TestInterestGroupObserver::kBid, origin, "cars", 2.0},
{"1", TestInterestGroupObserver::kBid, origin2, "shoes", 1.0},
{"1", TestInterestGroupObserver::kWin, origin, "cars"}});
// `prev_wins` of `test_url`'s interest group cars is updated in storage.
storage_interest_groups = GetInterestGroupsForOwner(origin);
storage_interest_groups2 = GetInterestGroupsForOwner(origin2);
// Remove the above two loads from the observer.
WaitForAccessObserved(
{{TestInterestGroupObserver::kLoaded, origin, "cars"},
{TestInterestGroupObserver::kLoaded, origin2, "shoes"}});
{{"global", TestInterestGroupObserver::kLoaded, origin, "cars"},
{"global", TestInterestGroupObserver::kLoaded, origin2, "shoes"}});
EXPECT_EQ(storage_interest_groups->GetInterestGroups()[0]
->bidding_browser_signals->prev_wins.size(),
1u);
@@ -10817,18 +10816,19 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionMultipleAuctions) {
// Run auction again. Interest group shoes of owner `test_url2` wins.
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad2_url);
// Need to wait again.
WaitForAccessObserved({{TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{TestInterestGroupObserver::kLoaded, origin, "cars"},
{TestInterestGroupObserver::kBid, origin2, "shoes"},
{TestInterestGroupObserver::kWin, origin2, "shoes"}});
WaitForAccessObserved(
{{"2", TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{"2", TestInterestGroupObserver::kLoaded, origin, "cars"},
{"2", TestInterestGroupObserver::kBid, origin2, "shoes", 1.0},
{"2", TestInterestGroupObserver::kWin, origin2, "shoes"}});
// `test_url2`'s interest group shoes has one `prev_wins` in storage.
storage_interest_groups = GetInterestGroupsForOwner(origin);
storage_interest_groups2 = GetInterestGroupsForOwner(origin2);
// Remove the above two loads from the observer.
WaitForAccessObserved(
{{TestInterestGroupObserver::kLoaded, origin, "cars"},
{TestInterestGroupObserver::kLoaded, origin2, "shoes"}});
{{"global", TestInterestGroupObserver::kLoaded, origin, "cars"},
{"global", TestInterestGroupObserver::kLoaded, origin2, "shoes"}});
EXPECT_EQ(storage_interest_groups->GetInterestGroups()[0]
->bidding_browser_signals->prev_wins.size(),
1u);
@@ -10860,9 +10860,9 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionMultipleAuctions) {
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad2_url);
// Need to wait again.
WaitForAccessObserved({
{TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{TestInterestGroupObserver::kBid, origin2, "shoes"},
{TestInterestGroupObserver::kWin, origin2, "shoes"},
{"3", TestInterestGroupObserver::kLoaded, origin2, "shoes"},
{"3", TestInterestGroupObserver::kBid, origin2, "shoes", 1.0},
{"3", TestInterestGroupObserver::kWin, origin2, "shoes"},
});
// `test_url2`'s interest group shoes has two `prev_wins` in storage.
@@ -11557,6 +11557,7 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
}
IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, ComponentAuction) {
AttachInterestGroupObserver();
GURL test_url =
embedded_https_test_server().GetURL("a.test", "/page_with_iframe.html");
ASSERT_TRUE(NavigateToURL(shell(), test_url));
@@ -11597,6 +11598,16 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, ComponentAuction) {
embedded_https_test_server().GetURL("a.test",
"/interest_group/decision_logic.js"));
RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad_url);
WaitForAccessObserved({
{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"2", TestInterestGroupObserver::kTopLevelBid, test_origin, "cars", 1.0,
/*bid_currency=*/absl::nullopt, test_origin},
{"2", TestInterestGroupObserver::kWin, test_origin, "cars",
/*bid=*/absl::nullopt, /*bid_currency=*/absl::nullopt, test_origin},
});
}
// Test the case of a component argument in the case a bidder refuses to
@@ -11742,6 +11753,8 @@ class InterestGroupWorkletValidationBrowserTest
// the expected values.
IN_PROC_BROWSER_TEST_P(InterestGroupWorkletValidationBrowserTest,
ValidateWorkletParameters) {
AttachInterestGroupObserver();
// Use different hostnames for each participant, since
// `trusted_bidding_signals` only checks the hostname of certain parameters.
constexpr char kBidderHost[] = "a.test";
@@ -11928,6 +11941,18 @@ IN_PROC_BROWSER_TEST_P(InterestGroupWorkletValidationBrowserTest,
embedded_https_test_server().GetURL(kSellerHost, "/echo?report_seller"));
WaitForUrl(
embedded_https_test_server().GetURL(kSellerHost, "/echo?report_bidder"));
WaitForAccessObserved({
{"global", TestInterestGroupObserver::kJoin, second_bidder_origin,
"boats"},
{"global", TestInterestGroupObserver::kJoin, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, second_bidder_origin, "boats"},
{"1", TestInterestGroupObserver::kLoaded, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, second_bidder_origin, "boats",
1.0},
{"1", TestInterestGroupObserver::kBid, bidder_origin, "cars", 2.0, "USD"},
{"1", TestInterestGroupObserver::kWin, bidder_origin, "cars"},
});
}
INSTANTIATE_TEST_SUITE_P(
@@ -12114,6 +12139,8 @@ IN_PROC_BROWSER_TEST_P(InterestGroupComponentWorkletValidationBrowserTest,
/*name=*/"cars"));
}
AttachInterestGroupObserver();
ASSERT_EQ(kSuccess,
JoinInterestGroupAndVerify(
blink::TestInterestGroupBuilder(/*owner=*/bidder_origin,
@@ -12360,6 +12387,18 @@ IN_PROC_BROWSER_TEST_P(InterestGroupComponentWorkletValidationBrowserTest,
kComponentSellerHost, "/echo?report_component_seller"));
WaitForUrl(embedded_https_test_server().GetURL(kBidderHost,
"/echo?report_bidder"));
WaitForAccessObserved({
{"global", TestInterestGroupObserver::kJoin, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, bidder_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, bidder_origin, "cars", 2.0,
"USD"},
{"2", TestInterestGroupObserver::kTopLevelBid, bidder_origin, "cars",
42.0, "CAD", component_seller_origin},
{"2", TestInterestGroupObserver::kWin, bidder_origin, "cars",
/*bid=*/absl::nullopt, /*bid_currency=*/absl::nullopt,
component_seller_origin},
});
}
}
@@ -16469,19 +16508,19 @@ IN_PROC_BROWSER_TEST_P(LeaveAdInterestGroupFromAdComponentBrowserTest,
if (IsLeaveAdInterestGroupFromAdComponentEnabled()) {
// InterestGroupAccessObserver should see the join, auction and the leave.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"},
{TestInterestGroupObserver::kLeave, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kLeave, test_origin, "cars"}});
} else {
// InterestGroupAccessObserver should see the join and auction, but not the
// leave.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
}
// The state of the interest groups depends on the feature toggle.
@@ -16506,10 +16545,10 @@ IN_PROC_BROWSER_TEST_P(LeaveAdInterestGroupFromAdComponentBrowserTest,
// implicit leave since it was blocked due to cross origin to the interest
// group owner.
WaitForAccessObserved(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
// The ad should not leave the interest group.
EXPECT_EQ(1u, GetAllInterestGroups().size());
@@ -18335,18 +18374,19 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
auction_config, should_win ? additional_bid_ad_url : ad_url);
WaitForUrl(embedded_https_test_server().GetURL("a.test",
"/echoall?report_seller"));
if (should_win) {
WaitForUrl(embedded_https_test_server().GetURL(
"a.test", "/echoall?report_bidder_additional"));
EXPECT_FALSE(HasServerSeenUrl(embedded_https_test_server().GetURL(
"a.test", "/echoall?report_bidder")));
WaitForAccessObserved({
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kAdditionalBid, additional_bid_origin,
"campaign123"},
{TestInterestGroupObserver::kAdditionalBidWin, additional_bid_origin,
"campaign123"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kAdditionalBid,
additional_bid_origin, "campaign123", 1.99},
{"1", TestInterestGroupObserver::kAdditionalBidWin,
additional_bid_origin, "campaign123"},
});
} else {
WaitForUrl(embedded_https_test_server().GetURL("a.test",
@@ -18354,11 +18394,11 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
EXPECT_FALSE(HasServerSeenUrl(embedded_https_test_server().GetURL(
"a.test", "/echoall?report_bidder_additional")));
WaitForAccessObserved(
{{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kBid, test_origin, "cars"},
{TestInterestGroupObserver::kAdditionalBid, additional_bid_origin,
"campaign123"},
{TestInterestGroupObserver::kWin, test_origin, "cars"}});
{{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
{"1", TestInterestGroupObserver::kAdditionalBid,
additional_bid_origin, "campaign123", 0.1},
{"1", TestInterestGroupObserver::kWin, test_origin, "cars"}});
}
}
}
@@ -18417,9 +18457,9 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
WaitForUrl(embedded_https_test_server().GetURL(
"a.test", "/echoall?report_bidder_additional"));
WaitForAccessObserved({
{TestInterestGroupObserver::kAdditionalBid, additional_bid_origin,
"campaign123"},
{TestInterestGroupObserver::kAdditionalBidWin, additional_bid_origin,
{"1", TestInterestGroupObserver::kAdditionalBid, additional_bid_origin,
"campaign123", 2.0},
{"1", TestInterestGroupObserver::kAdditionalBidWin, additional_bid_origin,
"campaign123"},
});
}
@@ -20162,6 +20202,7 @@ IN_PROC_BROWSER_TEST_F(
// so it does bid and win.
IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
AdditionalBidOnComponentAuctionWithNoNegativeIGDoesBid) {
AttachInterestGroupObserver();
URLLoaderMonitor url_loader_monitor;
constexpr char kTestOrigin[] = "a.test";
@@ -20235,6 +20276,19 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
kTestOrigin, "/echoall?report_bidder_additional"));
EXPECT_FALSE(HasServerSeenUrl(embedded_https_test_server().GetURL(
kTestOrigin, "/echoall?report_bidder")));
url::Origin bid_origin = url::Origin::Create(test_url);
WaitForAccessObserved(
{{"global", TestInterestGroupObserver::kJoin, bid_origin, "cars"},
{"1", TestInterestGroupObserver::kLoaded, bid_origin, "cars"},
{"1", TestInterestGroupObserver::kAdditionalBid, bid_origin,
"campaign123", 1.99},
{"1", TestInterestGroupObserver::kBid, bid_origin, "cars", 1.0},
{"2", TestInterestGroupObserver::kTopLevelAdditionalBid, bid_origin,
"campaign123", 1.99, /*bid_currency=*/std::nullopt,
/*component_seller_origin=*/bid_origin},
{"2", TestInterestGroupObserver::kAdditionalBidWin, bid_origin,
"campaign123", /*bid=*/std::nullopt, /*bid_currency=*/std::nullopt,
/*component_seller_origin=*/bid_origin}});
}
// Test to make sure that Promises configuration fields that are checked early
@@ -20314,11 +20368,11 @@ IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, NotificationOrder) {
// Expect events to be in order.
WaitForAccessObservedInOrder(
{{TestInterestGroupObserver::kJoin, test_origin, "cars"},
{TestInterestGroupObserver::kJoin, test_origin, "golf carts"},
{TestInterestGroupObserver::kClear, test_origin, "golf carts"},
{TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{TestInterestGroupObserver::kLeave, test_origin, "cars"}});
{{"global", TestInterestGroupObserver::kJoin, test_origin, "cars"},
{"global", TestInterestGroupObserver::kJoin, test_origin, "golf carts"},
{"global", TestInterestGroupObserver::kClear, test_origin, "golf carts"},
{"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
{"global", TestInterestGroupObserver::kLeave, test_origin, "cars"}});
}
// Make sure we don't crash when cross-frame promise resolution tries to notify

@@ -306,7 +306,10 @@ void InterestGroupManagerImpl::OnClearOriginJoinedInterestGroupsComplete(
const url::Origin& owner,
std::vector<std::string> left_interest_group_names) {
for (const auto& name : left_interest_group_names) {
NotifyInterestGroupAccessed(InterestGroupObserver::kClear, owner, name);
NotifyInterestGroupAccessed(
/*devtools_auction_id=*/std::nullopt, InterestGroupObserver::kClear,
owner, name, /*component_seller_origin=*/std::nullopt,
/*bid=*/std::nullopt, /*bid_currency=*/std::nullopt);
}
}
@@ -391,12 +394,14 @@ void InterestGroupManagerImpl::GetAllInterestGroupOwners(
}
void InterestGroupManagerImpl::GetInterestGroupsForOwner(
const std::optional<std::string>& devtools_auction_id,
const url::Origin& owner,
base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback) {
caching_storage_.GetInterestGroupsForOwner(
owner,
base::BindOnce(&InterestGroupManagerImpl::OnGetInterestGroupsComplete,
weak_factory_.GetWeakPtr(), std::move(callback)));
weak_factory_.GetWeakPtr(), std::move(callback),
devtools_auction_id));
}
void InterestGroupManagerImpl::DeleteInterestGroupData(
@@ -527,8 +532,10 @@ void InterestGroupManagerImpl::LoadNextInterestGroupAdAuctionData(
if (!owners.empty()) {
url::Origin next_owner = std::move(owners.back());
owners.pop_back();
// Since a single B&A blob can be associated with multiple auctions, we
// can't link these loads to a specific one.
GetInterestGroupsForOwner(
next_owner,
/*devtools_auction_id=*/absl::nullopt, next_owner,
base::BindOnce(
&InterestGroupManagerImpl::OnLoadedNextInterestGroupAdAuctionData,
weak_factory_.GetWeakPtr(), std::move(state), std::move(owners),
@@ -674,8 +681,6 @@ void InterestGroupManagerImpl::UpdateInterestGroup(
const blink::InterestGroupKey& group_key,
InterestGroupUpdate update,
base::OnceCallback<void(bool)> callback) {
NotifyInterestGroupAccessed(InterestGroupObserver::kUpdate, group_key.owner,
group_key.name);
caching_storage_.UpdateInterestGroup(
group_key, std::move(update),
base::BindOnce(&InterestGroupManagerImpl::OnUpdateComplete,
@@ -688,8 +693,11 @@ void InterestGroupManagerImpl::OnUpdateComplete(
const std::string& name,
base::OnceCallback<void(bool)> callback,
bool success) {
NotifyInterestGroupAccessed(InterestGroupObserver::kUpdate, owner_origin,
name);
NotifyInterestGroupAccessed(/*devtools_auction_id=*/std::nullopt,
InterestGroupObserver::kUpdate, owner_origin,
name, /*component_seller_origin=*/std::nullopt,
/*bid=*/std::nullopt,
/*bid_currency=*/std::nullopt);
std::move(callback).Run(success);
}
@@ -701,26 +709,35 @@ void InterestGroupManagerImpl::ReportUpdateFailed(
void InterestGroupManagerImpl::OnGetInterestGroupsComplete(
base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback,
const std::optional<std::string>& devtools_auction_id,
scoped_refptr<StorageInterestGroups> groups) {
for (const SingleStorageInterestGroup& group : groups->GetInterestGroups()) {
NotifyInterestGroupAccessed(InterestGroupObserver::kLoaded,
group->interest_group.owner,
group->interest_group.name);
NotifyInterestGroupAccessed(
devtools_auction_id, InterestGroupObserver::kLoaded,
group->interest_group.owner, group->interest_group.name,
/*component_seller_origin=*/std::nullopt,
/*bid=*/std::nullopt, /*bid_currency=*/std::nullopt);
}
std::move(callback).Run(std::move(groups));
}
void InterestGroupManagerImpl::NotifyInterestGroupAccessed(
base::optional_ref<const std::string> devtools_auction_id,
InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) {
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) {
// Don't bother getting the time if there are no observers.
if (observers_.empty()) {
return;
}
base::Time now = base::Time::Now();
for (InterestGroupObserver& observer : observers_) {
observer.OnInterestGroupAccessed(now, type, owner_origin, name);
observer.OnInterestGroupAccessed(
devtools_auction_id, now, type, owner_origin, name,
component_seller_origin, bid, bid_currency);
}
}
@@ -823,8 +840,15 @@ InterestGroupManagerImpl::CreateNotifyInterestGroupAccessedCallback(
InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) {
// This is only used for join/leave, so no auction ID associated.
DCHECK(type == InterestGroupObserver::kJoin ||
type == InterestGroupObserver::kLeave);
return base::BindOnce(&InterestGroupManagerImpl::NotifyInterestGroupAccessed,
weak_factory_.GetWeakPtr(), type, owner_origin, name);
weak_factory_.GetWeakPtr(),
/*devtools_auction_id=*/std::nullopt, type,
owner_origin, name,
/*component_seller_origin=*/std::nullopt,
/*bid=*/std::nullopt, /*bid_currency=*/std::nullopt);
}
} // namespace content

@@ -21,6 +21,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/types/expected.h"
#include "base/types/optional_ref.h"
#include "content/browser/interest_group/auction_process_manager.h"
#include "content/browser/interest_group/bidding_and_auction_serializer.h"
#include "content/browser/interest_group/bidding_and_auction_server_key_fetcher.h"
@@ -106,11 +107,19 @@ class CONTENT_EXPORT InterestGroupManagerImpl : public InterestGroupManager {
kWin,
kAdditionalBidWin,
kClear,
kTopLevelBid,
kTopLevelAdditionalBid
};
virtual void OnInterestGroupAccessed(const base::Time& access_time,
AccessType type,
const url::Origin& owner_origin,
const std::string& name) = 0;
virtual void OnInterestGroupAccessed(
base::optional_ref<const std::string> devtools_auction_id,
base::Time access_time,
AccessType type,
const url::Origin& owner_origin,
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) = 0;
};
// InterestGroupManager overrides:
@@ -271,6 +280,7 @@ class CONTENT_EXPORT InterestGroupManagerImpl : public InterestGroupManager {
// Gets a list of all interest groups with their bidding information
// associated with the provided owner.
void GetInterestGroupsForOwner(
const std::optional<std::string>& devtools_auction_id,
const url::Origin& owner,
base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback);
@@ -421,9 +431,14 @@ class CONTENT_EXPORT InterestGroupManagerImpl : public InterestGroupManager {
// database (can't log them all before the database update, since for, e.g.,
// calls to retrieve all interest groups for an owner, the name may not be
// known until after the database has been accessed).
void NotifyInterestGroupAccessed(InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name);
void NotifyInterestGroupAccessed(
base::optional_ref<const std::string> devtools_auction_id,
InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency);
private:
// InterestGroupUpdateManager calls private members to write updates to the
@@ -525,6 +540,7 @@ class CONTENT_EXPORT InterestGroupManagerImpl : public InterestGroupManager {
void OnGetInterestGroupsComplete(
base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback,
const std::optional<std::string>& devtools_auction_id,
scoped_refptr<StorageInterestGroups> groups);
// Dequeues and sends the first report request in `report_requests_` queue,

@@ -89,10 +89,14 @@ void TestInterestGroupManagerImpl::EnqueueReports(
}
void TestInterestGroupManagerImpl::OnInterestGroupAccessed(
const base::Time& access_time,
base::optional_ref<const std::string> devtools_auction_id,
base::Time access_time,
AccessType type,
const url::Origin& owner_origin,
const std::string& name) {
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) {
if (type == AccessType::kBid) {
interest_groups_that_bid_.emplace_back(owner_origin, name);
}

@@ -69,10 +69,15 @@ class TestInterestGroupManagerImpl
//
// This is used instead of a virtual method for tracking bids, since it has
// all the information that's needed.
void OnInterestGroupAccessed(const base::Time& access_time,
AccessType type,
const url::Origin& owner_origin,
const std::string& name) override;
void OnInterestGroupAccessed(
base::optional_ref<const std::string> devtools_auction_id,
base::Time access_time,
AccessType type,
const url::Origin& owner_origin,
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) override;
// KAnonymityServiceDelegate implementation:
void JoinSet(std::string id,

@@ -10,6 +10,7 @@
#include <vector>
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "content/browser/interest_group/interest_group_manager_impl.h"
#include "content/common/content_export.h"
@@ -19,16 +20,59 @@
namespace content {
TestInterestGroupObserver::Entry::Entry(
std::string devtools_auction_id,
InterestGroupManagerImpl::InterestGroupObserver::AccessType access_type,
url::Origin owner_origin,
std::string ig_name,
std::optional<double> bid,
std::optional<std::string> bid_currency,
std::optional<url::Origin> component_seller_origin)
: devtools_auction_id(std::move(devtools_auction_id)),
access_type(access_type),
owner_origin(std::move(owner_origin)),
ig_name(std::move(ig_name)),
bid(std::move(bid)),
bid_currency(std::move(bid_currency)),
component_seller_origin(std::move(component_seller_origin)) {}
TestInterestGroupObserver::Entry::Entry(const Entry&) = default;
TestInterestGroupObserver::Entry::~Entry() = default;
TestInterestGroupObserver::Entry& TestInterestGroupObserver::Entry::operator=(
const Entry&) = default;
bool TestInterestGroupObserver::Entry::operator==(const Entry&) const = default;
TestInterestGroupObserver::TestInterestGroupObserver() = default;
TestInterestGroupObserver::~TestInterestGroupObserver() = default;
void TestInterestGroupObserver::OnInterestGroupAccessed(
const base::Time& access_time,
base::optional_ref<const std::string> devtools_auction_id,
base::Time access_time,
InterestGroupManagerImpl::InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) {
accesses_.emplace_back(type, owner_origin, name);
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) {
// Hide the randomness of auction IDs for easier testing by renaming them to
// sequential integers (and "global" if not set)
std::string normalized_auction_id = "global";
if (devtools_auction_id.has_value()) {
auto it = seen_auction_ids_.find(*devtools_auction_id);
if (it != seen_auction_ids_.end()) {
normalized_auction_id = it->second;
} else {
normalized_auction_id =
base::NumberToString(seen_auction_ids_.size() + 1);
seen_auction_ids_[*devtools_auction_id] = normalized_auction_id;
}
}
accesses_.emplace_back(normalized_auction_id, type, owner_origin, name, bid,
bid_currency.CopyAsOptional(),
component_seller_origin.CopyAsOptional());
if (run_loop_ && accesses_.size() >= expected_.size()) {
run_loop_->Quit();
@@ -65,4 +109,28 @@ void TestInterestGroupObserver::WaitForAccessesInOrder(
accesses_.clear();
}
void PrintTo(const TestInterestGroupObserver::Entry& e, std::ostream* os) {
*os << "(";
*os << e.devtools_auction_id << ", ";
*os << e.access_type << ", ";
*os << e.owner_origin.Serialize() << ", ";
*os << e.ig_name << ", ";
if (e.bid.has_value()) {
*os << e.bid.value() << ", ";
} else {
*os << "(no bid), ";
}
if (e.bid_currency.has_value()) {
*os << e.bid_currency.value() << ", ";
} else {
*os << "(no bid_currency), ";
}
if (e.component_seller_origin.has_value()) {
*os << e.component_seller_origin->Serialize();
} else {
*os << "(no component_seller_origin)";
}
*os << ")";
}
} // namespace content

@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_INTEREST_GROUP_TEST_INTEREST_GROUP_OBSERVER_H_
#define CONTENT_BROWSER_INTEREST_GROUP_TEST_INTEREST_GROUP_OBSERVER_H_
#include <map>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include <vector>
@@ -22,10 +25,31 @@ namespace content {
class TestInterestGroupObserver
: public InterestGroupManagerImpl::InterestGroupObserver {
public:
using Entry =
std::tuple<InterestGroupManagerImpl::InterestGroupObserver::AccessType,
url::Origin,
std::string>;
struct Entry {
Entry(
std::string devtools_auction_id,
InterestGroupManagerImpl::InterestGroupObserver::AccessType access_type,
url::Origin owner_origin,
std::string ig_name,
std::optional<double> bid = std::nullopt,
std::optional<std::string> bid_currency = std::nullopt,
std::optional<url::Origin> component_seller_origin = std::nullopt);
Entry(const Entry&);
~Entry();
Entry& operator=(const Entry&);
bool operator==(const Entry&) const;
// The auction ID is replaced by either "global" or a number starting from
// 1, strinfigied.
std::string devtools_auction_id;
InterestGroupManagerImpl::InterestGroupObserver::AccessType access_type;
url::Origin owner_origin;
std::string ig_name;
std::optional<double> bid;
std::optional<std::string> bid_currency;
std::optional<url::Origin> component_seller_origin;
};
TestInterestGroupObserver();
~TestInterestGroupObserver() override;
@@ -36,10 +60,14 @@ class TestInterestGroupObserver
// InterestGroupManagerImpl::InterestGroupObserver implementation:
void OnInterestGroupAccessed(
const base::Time& access_time,
base::optional_ref<const std::string> devtools_auction_id,
base::Time access_time,
InterestGroupManagerImpl::InterestGroupObserver::AccessType type,
const url::Origin& owner_origin,
const std::string& name) override;
const std::string& name,
base::optional_ref<const url::Origin> component_seller_origin,
std::optional<double> bid,
base::optional_ref<const std::string> bid_currency) override;
// Waits until exactly the expected events have seen, in the passed in order.
// Once they have been observed, clears the log of the previous events. Note
@@ -54,11 +82,15 @@ class TestInterestGroupObserver
void WaitForAccessesInOrder(const std::vector<Entry>& expected);
private:
std::map<std::string, std::string> seen_auction_ids_;
std::vector<Entry> accesses_;
std::vector<Entry> expected_;
std::unique_ptr<base::RunLoop> run_loop_;
};
// Printer for gtest.
void PrintTo(const TestInterestGroupObserver::Entry& e, std::ostream* os);
} // namespace content
#endif // CONTENT_BROWSER_INTEREST_GROUP_TEST_INTEREST_GROUP_OBSERVER_H_

@@ -206,9 +206,10 @@ class RemoveInterestGroupTester {
static_cast<InterestGroupManagerImpl*>(
storage_partition_->GetInterestGroupManager())
->GetInterestGroupsForOwner(
origin, base::BindOnce(
&RemoveInterestGroupTester::GetInterestGroupsCallback,
base::Unretained(this), loop.QuitClosure()));
/*devtools_auction_id=*/std::nullopt, origin,
base::BindOnce(
&RemoveInterestGroupTester::GetInterestGroupsCallback,
base::Unretained(this), loop.QuitClosure()));
loop.Run();
return get_interest_group_success_;
}