0

Plumbing Private model training data from worklet to browser process.

This change passes data we get from `reportAggregateWin()` to the
browser so that it can be used to create a PMT request in a follow up
CL.

This change:
- Creates a mojom struct to carry this data over IPC
- Builds that struct using data we get from `reportAggregateWin()`
- Passes that struct from the bidder worklet to the IG auction
  reporter

This change modifies some previous tests to ensure they now validate the
private model training data that comes out of the worklet.

We also test that a struct is always built and passed when
`queueReportAggregateWin()` is called, no matter if there was an an
issue with `reportAggregateWin()` such as:
 - a error
 - timeout
 - no reportAggregateWin() function defined
 - no call to sendEncryptedTo()
 - if the payload size is greater than `payload_length`

Bug: 390160246
Change-Id: Ib3792af99a0e840209fc66288e8b4426f87a1cee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6312297
Reviewed-by: Dominic Farolino <dom@chromium.org>
Commit-Queue: Youssef Bourouphael <ybourouphael@google.com>
Reviewed-by: Maks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1428913}
This commit is contained in:
Youssef Bourouphael
2025-03-06 07:36:09 -08:00
committed by Chromium LUCI CQ
parent c3f9a2ca8d
commit 218f53d616
12 changed files with 618 additions and 72 deletions

@ -44,9 +44,11 @@
#include "content/public/browser/privacy_sandbox_invoking_api.h"
#include "content/public/common/content_client.h"
#include "content/services/auction_worklet/public/cpp/private_aggregation_reporting.h"
#include "content/services/auction_worklet/public/cpp/private_model_training_reporting.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/seller_worklet.mojom.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/client_security_state.mojom.h"
#include "third_party/blink/public/common/features.h"
@ -168,6 +170,31 @@ bool ValidateReportingPrivateAggregationRequests(
return true;
}
// If any part of the private model training request data is not valid, calls
// ReportBadMessage and returns false.
bool ValidatePrivateModelTrainingRequestData(
const auction_worklet::mojom::PrivateModelTrainingRequestDataPtr&
pmt_request_data) {
if (!base::FeatureList::IsEnabled(
blink::features::kFledgePrivateModelTraining)) {
return false;
}
if (pmt_request_data->payload_length > auction_worklet::kMaxPayloadLength) {
mojo::ReportBadMessage(
"queueReportAggregateWin(): modelingSignalsConfig.payloadLength "
"exceeds maximum length.");
return false;
}
if (pmt_request_data->payload.size() > pmt_request_data->payload_length) {
mojo::ReportBadMessage(
"sendEncryptedTo(): payload exceeds "
"modelingSignalsConfig.payloadLength.");
return false;
}
return true;
}
} // namespace
InterestGroupAuctionReporter::SellerWinningBidInfo::SellerWinningBidInfo() =
@ -930,6 +957,7 @@ void InterestGroupAuctionReporter::OnBidderWorkletFatalError(
/*bidder_ad_beacon_map=*/{},
/*bidder_ad_macro_map=*/{},
/*pa_requests=*/{},
/*pmt_request_data=*/nullptr,
/*timing_metrics=*/auction_worklet::mojom::BidderTimingMetrics::New(),
errors);
}
@ -941,6 +969,7 @@ void InterestGroupAuctionReporter::OnBidderReportWinComplete(
const base::flat_map<std::string, GURL>& bidder_ad_beacon_map,
const base::flat_map<std::string, std::string>& bidder_ad_macro_map,
PrivateAggregationRequests pa_requests,
auction_worklet::mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
auction_worklet::mojom::BidderTimingMetricsPtr timing_metrics,
const std::vector<std::string>& errors) {
TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "bidder_worklet_report_win",
@ -976,6 +1005,12 @@ void InterestGroupAuctionReporter::OnBidderReportWinComplete(
participant_data.percent_scripts_timeout =
timing_metrics->script_timed_out ? 100 : 0;
if (!pmt_request_data.is_null() &&
ValidatePrivateModelTrainingRequestData(pmt_request_data)) {
// TODO(ybourouphael): Add browser side implementation of Private Model
// Training API.
}
if (!ValidateReportingPrivateAggregationRequests(pa_requests)) {
pa_requests.clear();
}

@ -421,6 +421,8 @@ class CONTENT_EXPORT InterestGroupAuctionReporter {
const base::flat_map<std::string, GURL>& bidder_ad_beacon_map,
const base::flat_map<std::string, std::string>& bidder_ad_macro_map,
PrivateAggregationRequests pa_requests,
auction_worklet::mojom::PrivateModelTrainingRequestDataPtr
pmt_request_data,
auction_worklet::mojom::BidderTimingMetricsPtr timing_metrics,
const std::vector<std::string>& errors);

@ -42,6 +42,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/services/auction_worklet/public/cpp/private_model_training_reporting.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/real_time_reporting.mojom-forward.h"
#include "content/test/test_content_browser_client.h"
@ -53,6 +54,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/features_generated.h"
#include "third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h"
#include "third_party/blink/public/common/interest_group/auction_config.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"
@ -335,6 +337,8 @@ class InterestGroupAuctionReporterTest
base::flat_map<std::string, std::string> ad_macro_map = {},
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
pa_requests = {},
auction_worklet::mojom::PrivateModelTrainingRequestDataPtr
pmt_request_data = nullptr,
std::vector<std::string> errors = {}) {
auction_process_manager_.WaitForWinningBidderReload();
std::unique_ptr<MockBidderWorklet> bidder_worklet =
@ -342,7 +346,8 @@ class InterestGroupAuctionReporterTest
bidder_worklet->WaitForReportWin();
bidder_worklet->InvokeReportWinCallback(
std::move(report_url), std::move(ad_beacon_map),
std::move(ad_macro_map), std::move(pa_requests), std::move(errors));
std::move(ad_macro_map), std::move(pa_requests),
std::move(pmt_request_data), std::move(errors));
// Note that the bidder pipe is not automatically flushed on destruction, so
// need to destroy it manually. Flushing the pipe ensures that the reporter
@ -921,7 +926,9 @@ TEST_F(InterestGroupAuctionReporterTest, ComponentAuctionErrors) {
WaitForReportWinAndRunCallback(kBidderReportUrl, /*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, /*errors=*/{kBuyerError});
/*pa_requests=*/{},
/*pmt_request_data=*/nullptr,
/*errors=*/{kBuyerError});
interest_group_manager_impl_->ExpectReports(
{{InterestGroupManagerImpl::ReportType::kSendReportTo,
kBidderReportUrl}});
@ -1573,6 +1580,76 @@ TEST_F(InterestGroupAuctionReporterTest, RecordKAnonKeysToJoinLateNavigation) {
testing::UnorderedElementsAre());
}
class InterestGroupAuctionReporterPrivateModelTrainingEnabledTest
: public InterestGroupAuctionReporterTest {
public:
InterestGroupAuctionReporterPrivateModelTrainingEnabledTest() {
feature_list_.InitAndEnableFeature(
blink::features::kFledgePrivateModelTraining);
}
protected:
base::test::ScopedFeatureList feature_list_;
};
TEST_F(InterestGroupAuctionReporterPrivateModelTrainingEnabledTest,
PrivateModelTrainingRequestDataInvalidPayloadLength) {
SetUpAndStartSingleSellerAuction();
interest_group_auction_reporter_
->OnNavigateToWinningAdCallback(FrameTreeNodeId())
.Run();
WaitForReportResultAndRunCallback(kSellerScriptUrl, std::nullopt);
auto pmt_request_data =
auction_worklet::mojom::PrivateModelTrainingRequestData::New(
/*payload=*/mojo_base::BigBuffer(10),
/*payload_length*/ auction_worklet::kMaxPayloadLength + 1,
/*aggregation_coordinator_origin=*/GURL("https://aggregation.test"),
/*destination=*/GURL("https://destination.test"));
WaitForReportWinAndRunCallback(
std::nullopt, /*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{},
/*pmt_request_data=*/std::move(pmt_request_data));
EXPECT_EQ(
"queueReportAggregateWin(): modelingSignalsConfig.payloadLength "
"exceeds maximum length.",
TakeBadMessage());
WaitForCompletion();
}
TEST_F(InterestGroupAuctionReporterPrivateModelTrainingEnabledTest,
PrivateModelTrainingRequestDataInvalidPayloadSize) {
SetUpAndStartSingleSellerAuction();
interest_group_auction_reporter_
->OnNavigateToWinningAdCallback(FrameTreeNodeId())
.Run();
WaitForReportResultAndRunCallback(kSellerScriptUrl, std::nullopt);
auto pmt_request_data =
auction_worklet::mojom::PrivateModelTrainingRequestData::New(
/*payload=*/mojo_base::BigBuffer(10),
/*payload_length*/ 9,
/*aggregation_coordinator_origin=*/GURL("https://aggregation.test"),
/*destination=*/GURL("https://destination.test"));
WaitForReportWinAndRunCallback(
std::nullopt, /*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{},
/*pmt_request_data=*/std::move(pmt_request_data));
EXPECT_EQ(
"sendEncryptedTo(): payload exceeds "
"modelingSignalsConfig.payloadLength.",
TakeBadMessage());
WaitForCompletion();
}
// Check that private aggregation requests are passed along as expected. This
// creates an auction which is both passed aggregation reports from the bidding
// and scoring phase of the auction, and receives more from each reporting

@ -22,6 +22,7 @@
#include "content/browser/interest_group/auction_process_manager.h"
#include "content/public/browser/site_instance.h"
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-forward.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/real_time_reporting.mojom.h"
@ -348,11 +349,12 @@ void MockBidderWorklet::InvokeReportWinCallback(
base::flat_map<std::string, std::string> ad_macro_map,
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
pa_requests,
auction_worklet::mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
std::vector<std::string> errors) {
DCHECK(report_win_callback_);
std::move(report_win_callback_)
.Run(report_url, std::move(ad_beacon_map), std::move(ad_macro_map),
std::move(pa_requests),
std::move(pa_requests), std::move(pmt_request_data),
auction_worklet::mojom::BidderTimingMetrics::New(
/*js_fetch_latency=*/js_fetch_latency_,
/*wasm_fetch_latency=*/wasm_fetch_latency_,

@ -200,6 +200,8 @@ class MockBidderWorklet : public auction_worklet::mojom::BidderWorklet,
base::flat_map<std::string, std::string> ad_macro_map = {},
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
pa_requests = {},
auction_worklet::mojom::PrivateModelTrainingRequestDataPtr
pmt_request_data = nullptr,
std::vector<std::string> errors = {});
// Flushes the receiver pipe.

@ -20,6 +20,7 @@
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/i18n/number_formatting.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@ -42,11 +43,12 @@
#include "content/services/auction_worklet/direct_from_seller_signals_requester.h"
#include "content/services/auction_worklet/for_debugging_only_bindings.h"
#include "content/services/auction_worklet/private_aggregation_bindings.h"
#include "content/services/auction_worklet/private_model_training_bindings.h"
#include "content/services/auction_worklet/public/cpp/auction_network_events_delegate.h"
#include "content/services/auction_worklet/public/cpp/auction_worklet_features.h"
#include "content/services/auction_worklet/public/cpp/private_aggregation_reporting.h"
#include "content/services/auction_worklet/public/cpp/private_model_training_reporting.h"
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-shared.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/real_time_reporting.mojom.h"
@ -69,6 +71,7 @@
#include "context_recycler.h"
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@ -1112,7 +1115,7 @@ void BidderWorklet::V8State::ReportWin(
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, base::TimeDelta(),
/*pa_requests=*/{}, /*pmt_request_data=*/nullptr, base::TimeDelta(),
/*script_timed_out=*/true,
/*errors=*/{"reportWin() aborted due to zero timeout."});
return;
@ -1137,13 +1140,14 @@ void BidderWorklet::V8State::ReportWin(
base::OptionalToPtr(per_buyer_signals_json),
&args) ||
!v8_helper_->AppendJsonValue(context, seller_signals_json, &args)) {
PostReportWinCallbackToUserThread(std::move(callback),
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, base::TimeDelta(),
/*script_timed_out=*/false,
/*errors=*/std::vector<std::string>());
PostReportWinCallbackToUserThread(
std::move(callback),
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, /*pmt_request_data=*/nullptr, base::TimeDelta(),
/*script_timed_out=*/false,
/*errors=*/std::vector<std::string>());
return;
}
@ -1195,13 +1199,14 @@ void BidderWorklet::V8State::ReportWin(
browser_signal_top_level_seller_origin, bidding_signals_data_version,
kanon_status, reporting_timeout, browser_signals, browser_signals_dict);
if (!browser_signals_set) {
PostReportWinCallbackToUserThread(std::move(callback),
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, base::TimeDelta(),
/*script_timed_out=*/false,
/*errors=*/std::vector<std::string>());
PostReportWinCallbackToUserThread(
std::move(callback),
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{},
/*pa_requests=*/{}, /*pmt_request_data=*/nullptr, base::TimeDelta(),
/*script_timed_out=*/false,
/*errors=*/std::vector<std::string>());
return;
}
@ -1226,6 +1231,7 @@ void BidderWorklet::V8State::ReportWin(
/*report_url=*/std::nullopt,
/*ad_beacon_map=*/{},
/*ad_macro_map=*/{}, /*pa_requests=*/{},
/*pmt_request_data=*/nullptr,
base::TimeDelta(),
/*script_timed_out=*/false,
/*errors=*/std::move(errors_out));
@ -1252,7 +1258,8 @@ void BidderWorklet::V8State::ReportWin(
PostReportWinCallbackToUserThread(
std::move(callback), /*report_url=*/std::nullopt,
/*ad_beacon_map=*/{}, /*ad_macro_map=*/{},
/*pa_requests=*/{}, elapsed_timer.Elapsed(),
/*pa_requests=*/{}, /*pmt_request_data=*/nullptr,
elapsed_timer.Elapsed(),
/*script_timed_out=*/result == AuctionV8Helper::Result::kTimeout,
std::move(errors_out));
return;
@ -1294,13 +1301,14 @@ void BidderWorklet::V8State::ReportWin(
/*ad_beacon_map=*/{}, /*ad_macro_map=*/{},
context_recycler.private_aggregation_bindings()
->TakePrivateAggregationRequests(),
elapsed,
/*pmt_request_data=*/nullptr, elapsed,
/*script_timed_out=*/result == AuctionV8Helper::Result::kTimeout,
std::move(errors_out));
return;
}
// If there was a config that means they called queueReportAggregateWin
mojom::PrivateModelTrainingRequestDataPtr maybe_pmt_request_data;
// If there was a config that means they called `queueReportAggregateWin()`
if (context_recycler.report_bindings()
->modeling_signals_config()
.has_value()) {
@ -1308,7 +1316,17 @@ void BidderWorklet::V8State::ReportWin(
// `joinCount`, and `recency` were not accessed within `reportWin()`.
if (!context_recycler.report_win_lazy_filler()
->ShouldBlockSendEncrypted()) {
context_recycler.AddPrivateModelTrainingBindings();
if (context_recycler.report_bindings()
->modeling_signals_config()
->payload_length <= kMaxPayloadLength) {
context_recycler.AddPrivateModelTrainingBindings();
} else {
errors_out.push_back(
"queueReportAggregateWin(): modelingSignalsConfig's "
"`payloadLength` may not exceed " +
base::NumberToString(kMaxPayloadLength) + ".");
}
}
v8::LocalVector<v8::Value> report_aggregate_win_args(isolate);
@ -1339,6 +1357,42 @@ void BidderWorklet::V8State::ReportWin(
"reportAggregateWin", report_aggregate_win_args, total_timeout.get(),
maybe_report_aggregate_win_result_ret, errors_out);
}
if (context_recycler.private_model_training_bindings()) {
// To prevent leaking a bit, we always send a request if
// `reportAggregateWin()` is called. Therefore, even if
// `sendEncryptedTo()` is not called or `reportAggregateWin()` encounters
// an error/timeout, we send the data with an empty payload. We also send
// data with an empty payload if the payload's size exceeds the specified
// `payload_length`.
mojo_base::BigBuffer maybe_payload =
context_recycler.private_model_training_bindings()
->TakePayload()
.value_or(mojo_base::BigBuffer(0));
if (maybe_payload.size() > context_recycler.report_bindings()
->modeling_signals_config()
->payload_length) {
errors_out.push_back(
"sendEncryptedTo(): payload size may not exceed the specified "
"modelingSignalsConfig.payloadLength.");
maybe_payload = mojo_base::BigBuffer(0);
}
maybe_pmt_request_data = mojom::PrivateModelTrainingRequestData::New(
/*payload=*/std::move(maybe_payload),
/*payload_length=*/
context_recycler.report_bindings()
->modeling_signals_config()
->payload_length,
/*aggregation_coordinator_origin=*/
context_recycler.report_bindings()
->modeling_signals_config()
->aggregation_coordinator_origin,
/*destination=*/
context_recycler.report_bindings()
->modeling_signals_config()
->destination);
}
}
// This covers both the case where a report URL was provided, and the case one
// was not.
@ -1348,7 +1402,7 @@ void BidderWorklet::V8State::ReportWin(
context_recycler.register_ad_macro_bindings()->TakeAdMacroMap(),
context_recycler.private_aggregation_bindings()
->TakePrivateAggregationRequests(),
elapsed,
std::move(maybe_pmt_request_data), elapsed,
/*script_timed_out=*/false, std::move(errors_out));
}
@ -2217,6 +2271,7 @@ void BidderWorklet::V8State::PostReportWinCallbackToUserThread(
base::flat_map<std::string, GURL> ad_beacon_map,
base::flat_map<std::string, std::string> ad_macro_map,
PrivateAggregationRequests pa_requests,
mojom::PrivateModelTrainingRequestDataPtr maybe_pmt_request_data,
base::TimeDelta reporting_latency,
bool script_timed_out,
std::vector<std::string> errors) {
@ -2225,8 +2280,8 @@ void BidderWorklet::V8State::PostReportWinCallbackToUserThread(
FROM_HERE,
base::BindOnce(std::move(callback), std::move(report_url),
std::move(ad_beacon_map), std::move(ad_macro_map),
std::move(pa_requests), reporting_latency,
script_timed_out, std::move(errors)));
std::move(pa_requests), std::move(maybe_pmt_request_data),
reporting_latency, script_timed_out, std::move(errors)));
}
void BidderWorklet::V8State::PostErrorBidCallbackToUserThread(
@ -2921,6 +2976,7 @@ void BidderWorklet::DeliverReportWinOnUserThread(
base::flat_map<std::string, GURL> ad_beacon_map,
base::flat_map<std::string, std::string> ad_macro_map,
PrivateAggregationRequests pa_requests,
mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
base::TimeDelta reporting_latency,
bool script_timed_out,
std::vector<std::string> errors) {
@ -2931,6 +2987,7 @@ void BidderWorklet::DeliverReportWinOnUserThread(
std::move(task->callback)
.Run(std::move(report_url), std::move(ad_beacon_map),
std::move(ad_macro_map), std::move(pa_requests),
std::move(pmt_request_data),
mojom::BidderTimingMetrics::New(
/*js_fetch_latency=*/js_fetch_latency_,
/*wasm_fetch_latency=*/wasm_fetch_latency_,

@ -32,6 +32,7 @@
#include "content/services/auction_worklet/public/mojom/auction_shared_storage_host.mojom.h"
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom-forward.h"
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-forward.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
#include "content/services/auction_worklet/public/mojom/real_time_reporting.mojom.h"
@ -446,6 +447,7 @@ class CONTENT_EXPORT BidderWorklet : public mojom::BidderWorklet,
base::flat_map<std::string, GURL> ad_beacon_map,
base::flat_map<std::string, std::string> ad_macro_map,
PrivateAggregationRequests pa_requests,
mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
base::TimeDelta reporting_latency,
bool script_timed_out,
std::vector<std::string> errors)>;
@ -699,6 +701,7 @@ class CONTENT_EXPORT BidderWorklet : public mojom::BidderWorklet,
base::flat_map<std::string, GURL> ad_beacon_map,
base::flat_map<std::string, std::string> ad_macro_map,
PrivateAggregationRequests pa_requests,
mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
base::TimeDelta reporting_latency,
bool script_timed_out,
std::vector<std::string> errors);
@ -876,6 +879,7 @@ class CONTENT_EXPORT BidderWorklet : public mojom::BidderWorklet,
base::flat_map<std::string, GURL> ad_beacon_map,
base::flat_map<std::string, std::string> ad_macro_map,
PrivateAggregationRequests pa_requests,
mojom::PrivateModelTrainingRequestDataPtr pmt_request_data,
base::TimeDelta reporting_latency,
bool script_timed_out,
std::vector<std::string> errors);

File diff suppressed because it is too large Load Diff

@ -39,6 +39,10 @@ class PrivateModelTrainingBindings : public Bindings {
return payload_;
}
std::optional<mojo_base::BigBuffer> TakePayload() {
return std::move(payload_);
}
private:
// Sends encrypted modeling signals to the destination specified in
// modelingSignalsConfig. The input 'args' is expected to be a single

@ -6,6 +6,7 @@ source_set("cpp") {
"auction_network_events_delegate.h",
"private_aggregation_reporting.cc",
"private_aggregation_reporting.h",
"private_model_training_reporting.h",
"real_time_reporting.h",
]

@ -0,0 +1,18 @@
// Copyright 2025 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_SERVICES_AUCTION_WORKLET_PUBLIC_CPP_PRIVATE_MODEL_TRAINING_REPORTING_H_
#define CONTENT_SERVICES_AUCTION_WORKLET_PUBLIC_CPP_PRIVATE_MODEL_TRAINING_REPORTING_H_
#include <cstdint>
namespace auction_worklet {
// Represents the maximum payload length that can be sent in a request for the
// Private Model Training API.
static constexpr uint32_t kMaxPayloadLength = 10000;
} // namespace auction_worklet
#endif // CONTENT_SERVICES_AUCTION_WORKLET_PUBLIC_CPP_PRIVATE_MODEL_TRAINING_REPORTING_H_

@ -8,6 +8,7 @@ import "content/services/auction_worklet/public/mojom/private_aggregation_reques
import "content/services/auction_worklet/public/mojom/real_time_reporting.mojom";
import "content/services/auction_worklet/public/mojom/reject_reason.mojom";
import "content/services/auction_worklet/public/mojom/trusted_signals_cache.mojom";
import "mojo/public/mojom/base/big_buffer.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "third_party/blink/public/mojom/devtools/devtools_agent.mojom";
@ -184,6 +185,21 @@ struct BidderTimingMetrics {
bool script_timed_out;
};
// Represents data that needs to be passed to the browser process
// to create a request for the Private Model Training API.
struct PrivateModelTrainingRequestData {
// The raw data that will need to be passed to the browser.
// Will never have a size greater than the `payload_length`.
mojo_base.mojom.BigBuffer payload;
// The length specified within `queueReportAggregateWin()` as
// part of the `modelingSignalsConfig`, which may differ from the actual
// length of `payload` which was created within `reportAggregateWin()`.
// This is capped at 10000.
uint32 payload_length;
url.mojom.Url aggregation_coordinator_origin;
url.mojom.Url destination;
};
// Single use client for each GenerateBid() call. Allows deferring generating
// bids until after a bidder's interest groups have all received priority
// vectors, which allows for cancelling generate bid calls from lower priority
@ -625,6 +641,9 @@ interface BidderWorklet {
//
// `pa_requests` The various requests made to the Private Aggregation API.
//
// `pmt_request_data` The data needed to build a request for the
// Private Model Training API.
//
// `reporting_latency` How long it took to run the JavaScript for
// `reportWin()` (including the top-level).
//
@ -668,6 +687,7 @@ interface BidderWorklet {
map<string, url.mojom.Url> ad_beacon_map,
map<string, string> ad_macro_map,
array<PrivateAggregationRequest> pa_requests,
PrivateModelTrainingRequestData? pmt_request_data,
BidderTimingMetrics timing_metrics,
array<string> errors);