Revert "[shared storage] Implement sharedStorage.batchUpdate() for PA worklet"
This reverts commit f0cab8e234
.
Reason for revert: New tests are failing on linux-chromeos-dbg:
https://ci.chromium.org/ui/p/chromium/builders/ci/linux-chromeos-dbg/38480/test-results
Original change's description:
> [shared storage] Implement sharedStorage.batchUpdate() for PA worklet
>
> Add sharedStorage.batchUpdate() function. Parse arguments into
> the 'methods' sequence and a 'with_lock' optional flag, and
> propagate the result to the browser process to invoke the
> `SharedStorageLockManager::SharedStorageBatchUpdate()` API.
>
> This allows developers to perform multiple Shared Storage operations atomically within a single lock, as part of the Web
> Lock integration proposal:
> - https://github.com/WICG/shared-storage/pull/199
> - https://github.com/WICG/shared-storage/pull/205
>
> Fuchsia-Binary-Size: Size increase is unavoidable.
> Bug: 373899210
> Change-Id: Ic6e9f794d78523ec9f6b87f37fb5e91f17635c58
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6072850
> Commit-Queue: Yao Xiao <yaoxia@chromium.org>
> Reviewed-by: Maks Orlovich <morlovich@chromium.org>
> Reviewed-by: Cammie Smith Barnes <cammie@chromium.org>
> Reviewed-by: Giovanni Ortuno Urquidi <ortuno@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1401673}
Bug: 373899210
Change-Id: I46c27d924dae0684a07ec081095d8dbde970b6ca
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6123546
Owners-Override: Tim Sergeant <tsergeant@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Tim Sergeant <tsergeant@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1401696}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
74dcf0d502
commit
aaa8627166
content
browser
services
third_party/blink/web_tests/external/wpt/shared-storage
@ -80,32 +80,4 @@ void AuctionSharedStorageHost::SharedStorageUpdate(
|
|||||||
ToWebFeature(source_auction_worklet_function));
|
ToWebFeature(source_auction_worklet_function));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuctionSharedStorageHost::SharedStorageBatchUpdate(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
|
||||||
source_auction_worklet_function) {
|
|
||||||
if (with_lock && with_lock->starts_with('-')) {
|
|
||||||
receiver_set_.ReportBadMessage("Reserved lock name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameTreeNodeId main_frame_id =
|
|
||||||
receiver_set_.current_context()
|
|
||||||
.auction_runner_rfh->GetOutermostMainFrame()
|
|
||||||
->GetFrameTreeNodeId();
|
|
||||||
|
|
||||||
storage_partition_->GetSharedStorageRuntimeManager()
|
|
||||||
->lock_manager()
|
|
||||||
.SharedStorageBatchUpdate(std::move(methods_with_options), with_lock,
|
|
||||||
receiver_set_.current_context().worklet_origin,
|
|
||||||
AccessScope::kProtectedAudienceWorklet,
|
|
||||||
main_frame_id, base::DoNothing());
|
|
||||||
|
|
||||||
GetContentClient()->browser()->LogWebFeatureForCurrentPage(
|
|
||||||
receiver_set_.current_context().auction_runner_rfh,
|
|
||||||
ToWebFeature(source_auction_worklet_function));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace content
|
} // namespace content
|
||||||
|
@ -43,12 +43,6 @@ class CONTENT_EXPORT AuctionSharedStorageHost
|
|||||||
method_with_options,
|
method_with_options,
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
auction_worklet::mojom::AuctionWorkletFunction
|
||||||
source_auction_worklet_function) override;
|
source_auction_worklet_function) override;
|
||||||
void SharedStorageBatchUpdate(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
|
||||||
source_auction_worklet_function) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReceiverContext;
|
struct ReceiverContext;
|
||||||
|
@ -11184,7 +11184,14 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest, ModifierMethodTypeHierarchy) {
|
|||||||
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
||||||
/*ad_component_descriptors=*/std::nullopt,
|
/*ad_component_descriptors=*/std::nullopt,
|
||||||
/*modeling_signals=*/std::nullopt,
|
/*modeling_signals=*/std::nullopt,
|
||||||
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()));
|
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()),
|
||||||
|
/*expected_data_version=*/std::nullopt,
|
||||||
|
/*expected_errors=*/{},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
|
|
||||||
v8_helpers_[0]->v8_runner()->PostTask(
|
v8_helpers_[0]->v8_runner()->PostTask(
|
||||||
FROM_HERE, base::BindOnce(
|
FROM_HERE, base::BindOnce(
|
||||||
@ -11225,7 +11232,12 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*expected_bids=*/nullptr,
|
/*expected_bids=*/nullptr,
|
||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{method_and_error.second});
|
{method_and_error.second},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11252,7 +11264,12 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{"https://url.test/:5 Uncaught TypeError: The \"shared-storage\" "
|
{"https://url.test/:5 Uncaught TypeError: The \"shared-storage\" "
|
||||||
"Permissions Policy denied the method on sharedStorage."});
|
"Permissions Policy denied the method on sharedStorage."},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11288,7 +11305,12 @@ TEST_F(
|
|||||||
/*expected_bids=*/nullptr,
|
/*expected_bids=*/nullptr,
|
||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{method_and_error.second});
|
{method_and_error.second},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11312,7 +11334,12 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{"https://url.test/:5 Uncaught TypeError: The shared storage method "
|
{"https://url.test/:5 Uncaught TypeError: The shared storage method "
|
||||||
"object constructor cannot be called as a function."});
|
"object constructor cannot be called as a function."},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11342,7 +11369,14 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
||||||
/*ad_component_descriptors=*/std::nullopt,
|
/*ad_component_descriptors=*/std::nullopt,
|
||||||
/*modeling_signals=*/std::nullopt,
|
/*modeling_signals=*/std::nullopt,
|
||||||
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()));
|
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()),
|
||||||
|
/*expected_data_version=*/std::nullopt,
|
||||||
|
/*expected_errors=*/{},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
v8_helpers_[0]->v8_runner()->PostTask(
|
v8_helpers_[0]->v8_runner()->PostTask(
|
||||||
@ -11377,252 +11411,12 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*expected_bids=*/nullptr,
|
/*expected_bids=*/nullptr,
|
||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{"https://url.test/:6 Uncaught Error 123."});
|
{"https://url.test/:6 Uncaught Error 123."},
|
||||||
}
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
/*expected_set_priority=*/std::nullopt,
|
||||||
SharedStorageBatchUpdate_NoArguments) {
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
/*expected_pa_requests=*/{});
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate();
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: sharedStorage.batchUpdate(): "
|
|
||||||
"at least 1 argument(s) are required."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_MethodsNotAnObject) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate(123);
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: sharedStorage.batchUpdate(): "
|
|
||||||
"Trouble converting argument 'methods' to a Sequence."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_MethodsNotASequence) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate({});
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: sharedStorage.batchUpdate(): "
|
|
||||||
"Trouble converting argument 'methods' to a Sequence."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_ErrorIteratingOverMethods) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
let o = {};
|
|
||||||
o[Symbol.iterator] = {};
|
|
||||||
|
|
||||||
sharedStorage.batchUpdate(o);
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:9 Uncaught TypeError: sharedStorage.batchUpdate(): "
|
|
||||||
"Trouble iterating over argument 'methods'."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_MethodsSequenceElementInvalidType) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate([123]);
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: Failed to convert value to "
|
|
||||||
"'SharedStorageModifierMethod'."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_MethodsSequenceElementUserDefinedType) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
|
|
||||||
class SharedStorageClearMethod {
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedStorage.batchUpdate([new SharedStorageClearMethod()]);
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:11 Uncaught TypeError: Failed to convert value to "
|
|
||||||
"'SharedStorageModifierMethod'."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_ReservedLockName) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate([], {withLock: '-abc'});
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: sharedStorage.batchUpdate(): "
|
|
||||||
"Lock name cannot start with '-'."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_PermissionsPolicyError) {
|
|
||||||
permissions_policy_state_ = mojom::AuctionWorkletPermissionsPolicyState::New(
|
|
||||||
/*private_aggregation_allowed=*/true,
|
|
||||||
/*shared_storage_allowed=*/false);
|
|
||||||
|
|
||||||
// Skip setting up `shared_storage_hosts_`, to be consistent with the
|
|
||||||
// permissions policy's enabled status. This matches production behavior.
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate([]);
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/nullptr,
|
|
||||||
/*expected_data_version=*/std::nullopt,
|
|
||||||
/*expected_errors=*/
|
|
||||||
{"https://url.test/:6 Uncaught TypeError: The \"shared-storage\" "
|
|
||||||
"Permissions Policy denied the method on sharedStorage."});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|
||||||
SharedStorageBatchUpdate_Success) {
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost test_shared_storage_host;
|
|
||||||
|
|
||||||
mojo::Receiver<auction_worklet::mojom::AuctionSharedStorageHost> receiver(
|
|
||||||
&test_shared_storage_host);
|
|
||||||
shared_storage_hosts_[0] = receiver.BindNewPipeAndPassRemote();
|
|
||||||
|
|
||||||
RunGenerateBidWithJavascriptExpectingResult(
|
|
||||||
CreateGenerateBidScript(
|
|
||||||
R"({ad: "ad", bid:1, render:"https://response.test/" })",
|
|
||||||
/*extra_code=*/R"(
|
|
||||||
sharedStorage.batchUpdate([]);
|
|
||||||
|
|
||||||
sharedStorage.batchUpdate([], {withLock: 'lock1'});
|
|
||||||
|
|
||||||
sharedStorage.batchUpdate([
|
|
||||||
new SharedStorageSetMethod('a', 'b'),
|
|
||||||
new SharedStorageAppendMethod('c', 'd'),
|
|
||||||
new SharedStorageDeleteMethod('e'),
|
|
||||||
new SharedStorageClearMethod({withLock: 'lock2'})
|
|
||||||
], {withLock: 'lock3'});
|
|
||||||
)"),
|
|
||||||
/*expected_bids=*/
|
|
||||||
mojom::BidderWorkletBid::New(
|
|
||||||
auction_worklet::mojom::BidRole::kUnenforcedKAnon, "\"ad\"", 1,
|
|
||||||
/*bid_currency=*/std::nullopt,
|
|
||||||
/*ad_cost=*/std::nullopt,
|
|
||||||
blink::AdDescriptor(GURL("https://response.test/")),
|
|
||||||
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
|
||||||
/*ad_component_descriptors=*/std::nullopt,
|
|
||||||
/*modeling_signals=*/std::nullopt,
|
|
||||||
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()));
|
|
||||||
|
|
||||||
// Make sure the shared storage mojom methods are invoked as they use a
|
|
||||||
// dedicated pipe.
|
|
||||||
task_environment_.RunUntilIdle();
|
|
||||||
|
|
||||||
using BatchRequest =
|
|
||||||
auction_worklet::TestAuctionSharedStorageHost::BatchRequest;
|
|
||||||
|
|
||||||
std::vector<content::MethodWithOptionsPtr> batch_methods1;
|
|
||||||
std::vector<content::MethodWithOptionsPtr> batch_methods2;
|
|
||||||
std::vector<content::MethodWithOptionsPtr> batch_methods3;
|
|
||||||
batch_methods3.push_back(MojomSetMethod(/*key=*/u"a",
|
|
||||||
/*value=*/u"b",
|
|
||||||
/*ignore_if_present=*/false));
|
|
||||||
batch_methods3.push_back(MojomAppendMethod(/*key=*/u"c",
|
|
||||||
/*value=*/u"d"));
|
|
||||||
batch_methods3.push_back(MojomDeleteMethod(/*key=*/u"e"));
|
|
||||||
batch_methods3.push_back(MojomClearMethod(/*with_lock=*/"lock2"));
|
|
||||||
|
|
||||||
EXPECT_THAT(
|
|
||||||
test_shared_storage_host.observed_batch_requests(),
|
|
||||||
testing::ElementsAre(
|
|
||||||
BatchRequest(std::move(batch_methods1),
|
|
||||||
/*with_lock=*/std::nullopt,
|
|
||||||
mojom::AuctionWorkletFunction::kBidderGenerateBid),
|
|
||||||
BatchRequest(std::move(batch_methods2),
|
|
||||||
/*with_lock=*/"lock1",
|
|
||||||
mojom::AuctionWorkletFunction::kBidderGenerateBid),
|
|
||||||
BatchRequest(std::move(batch_methods3),
|
|
||||||
/*with_lock=*/"lock3",
|
|
||||||
mojom::AuctionWorkletFunction::kBidderGenerateBid)));
|
|
||||||
|
|
||||||
v8_helpers_[0]->v8_runner()->PostTask(
|
|
||||||
FROM_HERE, base::BindOnce(
|
|
||||||
[](scoped_refptr<AuctionV8Helper> v8_helper) {
|
|
||||||
v8_helper->isolate()->RequestGarbageCollectionForTesting(
|
|
||||||
v8::Isolate::kFullGarbageCollection);
|
|
||||||
},
|
|
||||||
v8_helpers_[0]));
|
|
||||||
task_environment_.RunUntilIdle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
||||||
@ -11654,7 +11448,14 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
/*selected_buyer_and_seller_reporting_id=*/std::nullopt,
|
||||||
/*ad_component_descriptors=*/std::nullopt,
|
/*ad_component_descriptors=*/std::nullopt,
|
||||||
/*modeling_signals=*/std::nullopt,
|
/*modeling_signals=*/std::nullopt,
|
||||||
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()));
|
/*aggregate_win_signals=*/std::nullopt, base::TimeDelta()),
|
||||||
|
/*expected_data_version=*/std::nullopt,
|
||||||
|
/*expected_errors=*/{},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
|
|
||||||
// Make sure the shared storage mojom methods are invoked as they use a
|
// Make sure the shared storage mojom methods are invoked as they use a
|
||||||
// dedicated pipe.
|
// dedicated pipe.
|
||||||
@ -11702,7 +11503,12 @@ TEST_F(BidderWorkletSharedStorageAPIEnabledTest,
|
|||||||
/*expected_data_version=*/std::nullopt,
|
/*expected_data_version=*/std::nullopt,
|
||||||
/*expected_errors=*/
|
/*expected_errors=*/
|
||||||
{"https://url.test/:6 Uncaught TypeError: The \"shared-storage\" "
|
{"https://url.test/:6 Uncaught TypeError: The \"shared-storage\" "
|
||||||
"Permissions Policy denied the method on sharedStorage."});
|
"Permissions Policy denied the method on sharedStorage."},
|
||||||
|
/*expected_debug_loss_report_url=*/std::nullopt,
|
||||||
|
/*expected_debug_win_report_url=*/std::nullopt,
|
||||||
|
/*expected_set_priority=*/std::nullopt,
|
||||||
|
/*expected_update_priority_signals_overrides=*/{},
|
||||||
|
/*expected_pa_requests=*/{});
|
||||||
|
|
||||||
permissions_policy_state_ =
|
permissions_policy_state_ =
|
||||||
mojom::AuctionWorkletPermissionsPolicyState::New(
|
mojom::AuctionWorkletPermissionsPolicyState::New(
|
||||||
|
@ -22,13 +22,4 @@ interface AuctionSharedStorageHost {
|
|||||||
SharedStorageUpdate(
|
SharedStorageUpdate(
|
||||||
network.mojom.SharedStorageModifierMethodWithOptions method_with_options,
|
network.mojom.SharedStorageModifierMethodWithOptions method_with_options,
|
||||||
AuctionWorkletFunction source_auction_worklet_function);
|
AuctionWorkletFunction source_auction_worklet_function);
|
||||||
|
|
||||||
// Handle each modifier method within `methods_with_options`. If `with_lock`
|
|
||||||
// is provided, the methods within the batch will be executed with a lock
|
|
||||||
// acquired on the resource with name `with_lock`. `with_lock` shouldn't start
|
|
||||||
// with '-'.
|
|
||||||
SharedStorageBatchUpdate(
|
|
||||||
array<network.mojom.SharedStorageModifierMethodWithOptions> methods_with_options,
|
|
||||||
string? with_lock,
|
|
||||||
AuctionWorkletFunction source_auction_worklet_function);
|
|
||||||
};
|
};
|
||||||
|
@ -13,10 +13,6 @@
|
|||||||
#include "content/services/auction_worklet/public/mojom/auction_shared_storage_host.mojom.h"
|
#include "content/services/auction_worklet/public/mojom/auction_shared_storage_host.mojom.h"
|
||||||
#include "content/services/auction_worklet/webidl_compat.h"
|
#include "content/services/auction_worklet/webidl_compat.h"
|
||||||
#include "gin/converter.h"
|
#include "gin/converter.h"
|
||||||
#include "gin/handle.h"
|
|
||||||
#include "gin/public/gin_embedders.h"
|
|
||||||
#include "gin/public/wrapper_info.h"
|
|
||||||
#include "gin/wrappable.h"
|
|
||||||
#include "services/network/public/cpp/shared_storage_utils.h"
|
#include "services/network/public/cpp/shared_storage_utils.h"
|
||||||
#include "services/network/public/mojom/shared_storage.mojom.h"
|
#include "services/network/public/mojom/shared_storage.mojom.h"
|
||||||
#include "third_party/blink/public/common/features.h"
|
#include "third_party/blink/public/common/features.h"
|
||||||
@ -257,35 +253,49 @@ CreateMojomClearMethodFromParameters(
|
|||||||
std::move(method), std::move(with_lock));
|
std::move(method), std::move(with_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SharedStorageMethod represents a method for modifying shared storage. This
|
// SharedStorageMethod represents a method for modifying shared storage. It
|
||||||
// class inherits from gin::Wrappable to leverage gin's JavaScript object
|
// manages its own lifecycle through weak reference handling to support
|
||||||
// lifetime management capabilities. When the JavaScript object is garbage
|
// automatic garbage collection.
|
||||||
// collected, the corresponding C++ object will be properly cleaned up.
|
class SharedStorageMethod {
|
||||||
class SharedStorageMethod : public gin::Wrappable<SharedStorageMethod> {
|
|
||||||
public:
|
public:
|
||||||
static gin::WrapperInfo kWrapperInfo;
|
// Constructs a SharedStorageMethod with a Mojom method and sets up
|
||||||
|
// weak reference management.
|
||||||
|
//
|
||||||
|
// Responsibilities:
|
||||||
|
// - Create a V8 External wrapping the C++ object
|
||||||
|
// - Establish a persistent, weak reference to the External
|
||||||
|
// - Set the External as an internal field of the JavaScript object
|
||||||
|
// - Ensure proper cleanup when the JavaScript object is garbage collected
|
||||||
SharedStorageMethod(
|
SharedStorageMethod(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
v8::Local<v8::Object> obj,
|
v8::Local<v8::Object> obj,
|
||||||
network::mojom::SharedStorageModifierMethodWithOptionsPtr mojom_method)
|
network::mojom::SharedStorageModifierMethodWithOptionsPtr mojom_method)
|
||||||
: mojom_method_(std::move(mojom_method)) {
|
: mojom_method_(std::move(mojom_method)) {
|
||||||
gin::Handle<SharedStorageMethod> handler = gin::CreateHandle(isolate, this);
|
v8::Local<v8::External> external = v8::External::New(isolate, this);
|
||||||
// Use an index that won't interfere with gin's reserved indexes.
|
persistent_external_.Reset(isolate, external);
|
||||||
obj->SetInternalField(gin::kNumberOfInternalFields, handler.ToV8());
|
obj->SetInternalField(0, external);
|
||||||
|
persistent_external_.SetWeak(this, WeakCallback,
|
||||||
|
v8::WeakCallbackType::kParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
const network::mojom::SharedStorageModifierMethodWithOptionsPtr&
|
// Weak callback invoked by V8's garbage collector when the associated
|
||||||
mojom_method() const {
|
// JavaScript object becomes unreachable.
|
||||||
return mojom_method_;
|
//
|
||||||
|
// Responsibilities:
|
||||||
|
// - Clear the persistent external reference
|
||||||
|
// - Delete the SharedStorageMethod instance
|
||||||
|
static void WeakCallback(
|
||||||
|
const v8::WeakCallbackInfo<SharedStorageMethod>& data) {
|
||||||
|
SharedStorageMethod* method = data.GetParameter();
|
||||||
|
method->persistent_external_.Reset();
|
||||||
|
delete method;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
network::mojom::SharedStorageModifierMethodWithOptionsPtr mojom_method_;
|
network::mojom::SharedStorageModifierMethodWithOptionsPtr mojom_method_;
|
||||||
|
v8::Persistent<v8::External> persistent_external_;
|
||||||
};
|
};
|
||||||
|
|
||||||
gin::WrapperInfo SharedStorageMethod::kWrapperInfo = {gin::kEmbedderNativeGin};
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
SharedStorageBindings::SharedStorageBindings(
|
SharedStorageBindings::SharedStorageBindings(
|
||||||
@ -341,17 +351,6 @@ void SharedStorageBindings::AttachToContext(v8::Local<v8::Context> context) {
|
|||||||
clear_method_function)
|
clear_method_function)
|
||||||
.Check();
|
.Check();
|
||||||
|
|
||||||
// batchUpdate() is part of the Web Locks integration launch.
|
|
||||||
if (base::FeatureList::IsEnabled(blink::features::kSharedStorageWebLocks)) {
|
|
||||||
v8::Local<v8::Function> batch_update_function =
|
|
||||||
v8::Function::New(context, &SharedStorageBindings::BatchUpdate, v8_this)
|
|
||||||
.ToLocalChecked();
|
|
||||||
shared_storage
|
|
||||||
->Set(context, v8_helper_->CreateStringFromLiteral("batchUpdate"),
|
|
||||||
batch_update_function)
|
|
||||||
.Check();
|
|
||||||
}
|
|
||||||
|
|
||||||
context->Global()
|
context->Global()
|
||||||
->Set(context, v8_helper_->CreateStringFromLiteral("sharedStorage"),
|
->Set(context, v8_helper_->CreateStringFromLiteral("sharedStorage"),
|
||||||
shared_storage)
|
shared_storage)
|
||||||
@ -368,8 +367,7 @@ void SharedStorageBindings::AttachToContext(v8::Local<v8::Context> context) {
|
|||||||
v8::FunctionTemplate::New(v8_helper_->isolate(),
|
v8::FunctionTemplate::New(v8_helper_->isolate(),
|
||||||
&SharedStorageBindings::SetMethodConstructor,
|
&SharedStorageBindings::SetMethodConstructor,
|
||||||
v8_this);
|
v8_this);
|
||||||
set_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(
|
set_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
gin::kNumberOfInternalFields + 1);
|
|
||||||
set_method_ctor_template->Inherit(base_modifier_method_template);
|
set_method_ctor_template->Inherit(base_modifier_method_template);
|
||||||
set_method_ctor_template->SetClassName(
|
set_method_ctor_template->SetClassName(
|
||||||
v8_helper_->CreateStringFromLiteral(kSharedStorageSetMethodName));
|
v8_helper_->CreateStringFromLiteral(kSharedStorageSetMethodName));
|
||||||
@ -385,8 +383,7 @@ void SharedStorageBindings::AttachToContext(v8::Local<v8::Context> context) {
|
|||||||
v8::FunctionTemplate::New(
|
v8::FunctionTemplate::New(
|
||||||
v8_helper_->isolate(),
|
v8_helper_->isolate(),
|
||||||
&SharedStorageBindings::AppendMethodConstructor, v8_this);
|
&SharedStorageBindings::AppendMethodConstructor, v8_this);
|
||||||
append_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(
|
append_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
gin::kNumberOfInternalFields + 1);
|
|
||||||
append_method_ctor_template->Inherit(base_modifier_method_template);
|
append_method_ctor_template->Inherit(base_modifier_method_template);
|
||||||
append_method_ctor_template->SetClassName(
|
append_method_ctor_template->SetClassName(
|
||||||
v8_helper_->CreateStringFromLiteral(kSharedStorageAppendMethodName));
|
v8_helper_->CreateStringFromLiteral(kSharedStorageAppendMethodName));
|
||||||
@ -403,8 +400,7 @@ void SharedStorageBindings::AttachToContext(v8::Local<v8::Context> context) {
|
|||||||
v8::FunctionTemplate::New(
|
v8::FunctionTemplate::New(
|
||||||
v8_helper_->isolate(),
|
v8_helper_->isolate(),
|
||||||
&SharedStorageBindings::DeleteMethodConstructor, v8_this);
|
&SharedStorageBindings::DeleteMethodConstructor, v8_this);
|
||||||
delete_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(
|
delete_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
gin::kNumberOfInternalFields + 1);
|
|
||||||
delete_method_ctor_template->Inherit(base_modifier_method_template);
|
delete_method_ctor_template->Inherit(base_modifier_method_template);
|
||||||
delete_method_ctor_template->SetClassName(
|
delete_method_ctor_template->SetClassName(
|
||||||
v8_helper_->CreateStringFromLiteral(kSharedStorageDeleteMethodName));
|
v8_helper_->CreateStringFromLiteral(kSharedStorageDeleteMethodName));
|
||||||
@ -421,8 +417,7 @@ void SharedStorageBindings::AttachToContext(v8::Local<v8::Context> context) {
|
|||||||
v8::FunctionTemplate::New(
|
v8::FunctionTemplate::New(
|
||||||
v8_helper_->isolate(),
|
v8_helper_->isolate(),
|
||||||
&SharedStorageBindings::ClearMethodConstructor, v8_this);
|
&SharedStorageBindings::ClearMethodConstructor, v8_this);
|
||||||
clear_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(
|
clear_method_ctor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
gin::kNumberOfInternalFields + 1);
|
|
||||||
clear_method_ctor_template->Inherit(base_modifier_method_template);
|
clear_method_ctor_template->Inherit(base_modifier_method_template);
|
||||||
clear_method_ctor_template->SetClassName(
|
clear_method_ctor_template->SetClassName(
|
||||||
v8_helper_->CreateStringFromLiteral(kSharedStorageClearMethodName));
|
v8_helper_->CreateStringFromLiteral(kSharedStorageClearMethodName));
|
||||||
@ -515,131 +510,6 @@ void SharedStorageBindings::Clear(
|
|||||||
std::move(mojom_method), bindings->source_auction_worklet_function_);
|
std::move(mojom_method), bindings->source_auction_worklet_function_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void SharedStorageBindings::BatchUpdate(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
||||||
SharedStorageBindings* bindings = static_cast<SharedStorageBindings*>(
|
|
||||||
v8::External::Cast(*args.Data())->Value());
|
|
||||||
AuctionV8Helper* v8_helper = bindings->v8_helper_;
|
|
||||||
v8::Isolate* isolate = v8_helper->isolate();
|
|
||||||
|
|
||||||
AuctionV8Helper::TimeLimitScope time_limit_scope(v8_helper->GetTimeLimit());
|
|
||||||
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
mojom_methods;
|
|
||||||
|
|
||||||
scoped_refptr<AuctionV8Helper> ref_v8_helper(v8_helper);
|
|
||||||
auto collect_methods_callback = base::BindRepeating(
|
|
||||||
[](scoped_refptr<AuctionV8Helper> v8_helper,
|
|
||||||
AuctionV8Helper::TimeLimitScope& time_limit_scope,
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>&
|
|
||||||
mojom_methods,
|
|
||||||
v8::Local<v8::Value> method_val) -> IdlConvert::Status {
|
|
||||||
v8::Isolate* isolate = v8_helper->isolate();
|
|
||||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
|
||||||
|
|
||||||
static constexpr char kTypeConversionError[] =
|
|
||||||
"Failed to convert value to 'SharedStorageModifierMethod'";
|
|
||||||
|
|
||||||
v8::Local<v8::Object> method_obj;
|
|
||||||
if (!method_val->ToObject(context).ToLocal(&method_obj)) {
|
|
||||||
return IdlConvert::Status::MakeErrorMessage(kTypeConversionError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_obj->InternalFieldCount() !=
|
|
||||||
gin::kNumberOfInternalFields + 1) {
|
|
||||||
return IdlConvert::Status::MakeErrorMessage(kTypeConversionError);
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Local<v8::Value> internal_val =
|
|
||||||
method_obj->GetInternalField(gin::kNumberOfInternalFields)
|
|
||||||
.As<v8::Value>();
|
|
||||||
|
|
||||||
SharedStorageMethod* modifier_method = nullptr;
|
|
||||||
if (!gin::ConvertFromV8(isolate, internal_val, &modifier_method)) {
|
|
||||||
return IdlConvert::Status::MakeErrorMessage(kTypeConversionError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifier_method && modifier_method->mojom_method()) {
|
|
||||||
mojom_methods.push_back(modifier_method->mojom_method().Clone());
|
|
||||||
} else {
|
|
||||||
return IdlConvert::Status::MakeErrorMessage(kTypeConversionError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IdlConvert::Status::MakeSuccess();
|
|
||||||
},
|
|
||||||
ref_v8_helper, std::ref(time_limit_scope), std::ref(mojom_methods));
|
|
||||||
|
|
||||||
static constexpr char kErrorPrefix[] = "sharedStorage.batchUpdate(): ";
|
|
||||||
static constexpr char kSequenceConversionError[] =
|
|
||||||
"Trouble converting argument 'methods' to a Sequence.";
|
|
||||||
|
|
||||||
ArgsConverter args_converter(v8_helper, time_limit_scope, kErrorPrefix, &args,
|
|
||||||
/*min_required_args=*/1);
|
|
||||||
|
|
||||||
if (args_converter.is_success() && !args[0]->IsObject()) {
|
|
||||||
args_converter.SetStatus(IdlConvert::Status::MakeErrorMessage(
|
|
||||||
base::StrCat({kErrorPrefix, kSequenceConversionError})));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::initializer_list<std::string_view> error_subject = {
|
|
||||||
"argument 'methods'"};
|
|
||||||
|
|
||||||
v8::Local<v8::Object> iterable = args[0].As<v8::Object>();
|
|
||||||
v8::Local<v8::Object> iterator_factory;
|
|
||||||
|
|
||||||
if (args_converter.is_success()) {
|
|
||||||
args_converter.SetStatus(IdlConvert::CheckForSequence(
|
|
||||||
isolate, kErrorPrefix, error_subject, iterable, iterator_factory));
|
|
||||||
|
|
||||||
if (iterator_factory.IsEmpty()) {
|
|
||||||
if (args_converter.is_success()) {
|
|
||||||
args_converter.SetStatus(IdlConvert::Status::MakeErrorMessage(
|
|
||||||
base::StrCat({kErrorPrefix, kSequenceConversionError})));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args_converter.is_success()) {
|
|
||||||
args_converter.SetStatus(IdlConvert::ConvertSequence(
|
|
||||||
v8_helper, kErrorPrefix, error_subject, iterable, iterator_factory,
|
|
||||||
std::move(collect_methods_callback)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::string> with_lock;
|
|
||||||
if (args_converter.is_success() && args.Length() > 1) {
|
|
||||||
DictConverter options_dict_converter(
|
|
||||||
v8_helper, time_limit_scope,
|
|
||||||
"sharedStorage.batchUpdate 'options' argument ", args[1]);
|
|
||||||
options_dict_converter.GetOptional("withLock", with_lock);
|
|
||||||
args_converter.SetStatus(options_dict_converter.TakeStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args_converter.is_failed()) {
|
|
||||||
args_converter.TakeStatus().PropagateErrorsToV8(v8_helper);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bindings->shared_storage_permissions_policy_allowed_) {
|
|
||||||
isolate->ThrowException(v8::Exception::TypeError(
|
|
||||||
gin::StringToV8(isolate, kPermissionsPolicyError)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail for reserved lock name.
|
|
||||||
// https://w3c.github.io/web-locks/#resource-name
|
|
||||||
if (with_lock && with_lock->starts_with('-')) {
|
|
||||||
isolate->ThrowException(v8::Exception::TypeError(gin::StringToV8(
|
|
||||||
isolate,
|
|
||||||
base::StrCat({kErrorPrefix, "Lock name cannot start with '-'"}))));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings->shared_storage_host_->SharedStorageBatchUpdate(
|
|
||||||
std::move(mojom_methods), with_lock,
|
|
||||||
bindings->source_auction_worklet_function_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void SharedStorageBindings::SetMethodConstructor(
|
void SharedStorageBindings::SetMethodConstructor(
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
|
@ -39,7 +39,6 @@ class CONTENT_EXPORT SharedStorageBindings : public Bindings {
|
|||||||
static void Append(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Append(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Delete(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Delete(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Clear(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Clear(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void BatchUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
|
|
||||||
static void SetMethodConstructor(
|
static void SetMethodConstructor(
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "base/strings/to_string.h"
|
#include "base/strings/to_string.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
#include "content/public/test/shared_storage_test_utils.h"
|
|
||||||
#include "content/services/auction_worklet/auction_v8_helper.h"
|
#include "content/services/auction_worklet/auction_v8_helper.h"
|
||||||
#include "content/services/auction_worklet/public/cpp/auction_downloader.h"
|
#include "content/services/auction_worklet/public/cpp/auction_downloader.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
@ -168,33 +167,6 @@ TestAuctionSharedStorageHost::Request::operator=(Request&& other) = default;
|
|||||||
bool TestAuctionSharedStorageHost::Request::operator==(
|
bool TestAuctionSharedStorageHost::Request::operator==(
|
||||||
const Request& rhs) const = default;
|
const Request& rhs) const = default;
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest::BatchRequest(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
mojom::AuctionWorkletFunction source_auction_worklet_function)
|
|
||||||
: methods_with_options(std::move(methods_with_options)),
|
|
||||||
with_lock(with_lock),
|
|
||||||
source_auction_worklet_function(source_auction_worklet_function) {}
|
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest::~BatchRequest() = default;
|
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest::BatchRequest(
|
|
||||||
const BatchRequest& other)
|
|
||||||
: methods_with_options(
|
|
||||||
content::CloneSharedStorageMethods(other.methods_with_options)),
|
|
||||||
with_lock(other.with_lock),
|
|
||||||
source_auction_worklet_function(other.source_auction_worklet_function) {}
|
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest::BatchRequest(BatchRequest&& other) =
|
|
||||||
default;
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest&
|
|
||||||
TestAuctionSharedStorageHost::BatchRequest::operator=(BatchRequest&& other) =
|
|
||||||
default;
|
|
||||||
|
|
||||||
bool TestAuctionSharedStorageHost::BatchRequest::operator==(
|
|
||||||
const BatchRequest& rhs) const = default;
|
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::TestAuctionSharedStorageHost() = default;
|
TestAuctionSharedStorageHost::TestAuctionSharedStorageHost() = default;
|
||||||
|
|
||||||
TestAuctionSharedStorageHost::~TestAuctionSharedStorageHost() = default;
|
TestAuctionSharedStorageHost::~TestAuctionSharedStorageHost() = default;
|
||||||
@ -208,17 +180,6 @@ void TestAuctionSharedStorageHost::SharedStorageUpdate(
|
|||||||
Request(std::move(method_with_options), source_auction_worklet_function));
|
Request(std::move(method_with_options), source_auction_worklet_function));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestAuctionSharedStorageHost::SharedStorageBatchUpdate(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
|
||||||
source_auction_worklet_function) {
|
|
||||||
observed_batch_requests_.emplace_back(
|
|
||||||
BatchRequest(std::move(methods_with_options), with_lock,
|
|
||||||
source_auction_worklet_function));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestAuctionSharedStorageHost::ClearObservedRequests() {
|
void TestAuctionSharedStorageHost::ClearObservedRequests() {
|
||||||
observed_requests_.clear();
|
observed_requests_.clear();
|
||||||
}
|
}
|
||||||
|
@ -99,27 +99,6 @@ class TestAuctionSharedStorageHost : public mojom::AuctionSharedStorageHost {
|
|||||||
bool operator==(const Request& rhs) const;
|
bool operator==(const Request& rhs) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BatchRequest {
|
|
||||||
BatchRequest(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
mojom::AuctionWorkletFunction source_auction_worklet_function);
|
|
||||||
~BatchRequest();
|
|
||||||
|
|
||||||
BatchRequest(const BatchRequest& other);
|
|
||||||
BatchRequest& operator=(const BatchRequest& other) = delete;
|
|
||||||
BatchRequest(BatchRequest&& other);
|
|
||||||
BatchRequest& operator=(BatchRequest&& other);
|
|
||||||
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options;
|
|
||||||
std::optional<std::string> with_lock;
|
|
||||||
mojom::AuctionWorkletFunction source_auction_worklet_function;
|
|
||||||
|
|
||||||
bool operator==(const BatchRequest& rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
TestAuctionSharedStorageHost();
|
TestAuctionSharedStorageHost();
|
||||||
|
|
||||||
~TestAuctionSharedStorageHost() override;
|
~TestAuctionSharedStorageHost() override;
|
||||||
@ -130,26 +109,15 @@ class TestAuctionSharedStorageHost : public mojom::AuctionSharedStorageHost {
|
|||||||
method_with_options,
|
method_with_options,
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
auction_worklet::mojom::AuctionWorkletFunction
|
||||||
source_auction_worklet_function) override;
|
source_auction_worklet_function) override;
|
||||||
void SharedStorageBatchUpdate(
|
|
||||||
std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
|
|
||||||
methods_with_options,
|
|
||||||
const std::optional<std::string>& with_lock,
|
|
||||||
auction_worklet::mojom::AuctionWorkletFunction
|
|
||||||
source_auction_worklet_function) override;
|
|
||||||
|
|
||||||
const std::vector<Request>& observed_requests() const {
|
const std::vector<Request>& observed_requests() const {
|
||||||
return observed_requests_;
|
return observed_requests_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<BatchRequest>& observed_batch_requests() const {
|
|
||||||
return observed_batch_requests_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearObservedRequests();
|
void ClearObservedRequests();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Request> observed_requests_;
|
std::vector<Request> observed_requests_;
|
||||||
std::vector<BatchRequest> observed_batch_requests_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestAuctionNetworkEventsHandler
|
class TestAuctionNetworkEventsHandler
|
||||||
|
102
third_party/blink/web_tests/external/wpt/shared-storage/web-locks-pa-worklet-batch-update.tentative.https.window.js
vendored
102
third_party/blink/web_tests/external/wpt/shared-storage/web-locks-pa-worklet-batch-update.tentative.https.window.js
vendored
@ -1,102 +0,0 @@
|
|||||||
// META: script=/resources/testdriver.js
|
|
||||||
// META: script=/resources/testdriver-vendor.js
|
|
||||||
// META: script=/common/utils.js
|
|
||||||
// META: script=/fledge/tentative/resources/fledge-util.sub.js
|
|
||||||
// META: script=/common/subset-tests.js
|
|
||||||
// META: script=/shared-storage/resources/util.js
|
|
||||||
// META: script=/fenced-frame/resources/utils.js
|
|
||||||
// META: timeout=long
|
|
||||||
|
|
||||||
"use strict;"
|
|
||||||
|
|
||||||
subsetTest(promise_test, async test => {
|
|
||||||
let worklet = await sharedStorage.createWorklet('resources/simple-module.js');
|
|
||||||
|
|
||||||
const ancestor_key = token();
|
|
||||||
let url0 = generateURL("/shared-storage/resources/frame0.html",
|
|
||||||
[ancestor_key]);
|
|
||||||
let url1 = generateURL("/shared-storage/resources/frame1.html",
|
|
||||||
[ancestor_key]);
|
|
||||||
|
|
||||||
// Override the default resource path, as we are not running within the Fledge
|
|
||||||
// repository.
|
|
||||||
RESOURCE_PATH = '/fledge/tentative/resources/';
|
|
||||||
|
|
||||||
const pa_uuid = generateUuid(test);
|
|
||||||
|
|
||||||
let biddingLogicURL = createBiddingScriptURL(
|
|
||||||
{
|
|
||||||
generateBid:
|
|
||||||
`
|
|
||||||
sharedStorage.batchUpdate([
|
|
||||||
new SharedStorageAppendMethod('key', 'a'),
|
|
||||||
new SharedStorageAppendMethod('key', 'a')
|
|
||||||
], {withLock: 'lock1'});
|
|
||||||
|
|
||||||
return {};
|
|
||||||
`
|
|
||||||
});
|
|
||||||
|
|
||||||
let decisionLogicURL = createDecisionScriptURL(pa_uuid);
|
|
||||||
|
|
||||||
// Invoke `selectURL()` to perform the following steps:
|
|
||||||
// 1. Acquires the lock.
|
|
||||||
// 2. Reads the current value at the given key.
|
|
||||||
// 3. Waits for 500ms.
|
|
||||||
// 4. Sets the shared storage value to the read value appended with the given letter.
|
|
||||||
// 5. Releases the lock.
|
|
||||||
//
|
|
||||||
// After 100ms, run a Protected Audience auction that starts a worklet that:
|
|
||||||
// - Acquires the same named lock.
|
|
||||||
// - Executes two `append` methods, each appending the same letter.
|
|
||||||
//
|
|
||||||
// Expected behavior: After both of them finish, the value at the given key
|
|
||||||
// should contain the letter repeated three times.
|
|
||||||
//
|
|
||||||
// This demonstrates that:
|
|
||||||
// 1. The `withLock` option is effective, preventing the `batchUpdate()`
|
|
||||||
// method interfering with the "get and set" operation. If the lock were
|
|
||||||
// not used, the final value would likely be a single letter.
|
|
||||||
// 2. `batchUpdate()` correctly executes all `append` methods within the
|
|
||||||
// batch.
|
|
||||||
//
|
|
||||||
// Note: This test remains valid even if the `batchUpdate()` call happens
|
|
||||||
// outside the critical section protected by the lock within the worklet. The
|
|
||||||
// test effectively demonstrates mutual exclusion as long as there's a
|
|
||||||
// reasonable chance for `batchUpdate()` to occur while the worklet is still
|
|
||||||
// running.
|
|
||||||
let select_url_result = await worklet.selectURL(
|
|
||||||
"get-wait-set-within-lock",
|
|
||||||
[{url: url0}, {url: url1}],
|
|
||||||
{data: {'key': 'key',
|
|
||||||
'lock_name': 'lock1',
|
|
||||||
'append_letter': 'a'},
|
|
||||||
resolveToConfig: true});
|
|
||||||
|
|
||||||
// Busy wait for 100ms.
|
|
||||||
const startWaitTime = Date.now();
|
|
||||||
while (Date.now() - startWaitTime < 100) {}
|
|
||||||
|
|
||||||
// Run a Protected Audience auction which triggers `append()` with the same
|
|
||||||
// lock and the same letter.
|
|
||||||
await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
|
|
||||||
test,
|
|
||||||
{
|
|
||||||
uuid: pa_uuid,
|
|
||||||
interestGroupOverrides: {
|
|
||||||
name: pa_uuid,
|
|
||||||
biddingLogicURL: biddingLogicURL,
|
|
||||||
},
|
|
||||||
auctionConfigOverrides: {
|
|
||||||
decisionLogicURL: decisionLogicURL
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
attachFencedFrame(select_url_result, 'opaque-ads');
|
|
||||||
const result = await nextValueFromServer(ancestor_key);
|
|
||||||
assert_equals(result, "frame1_loaded");
|
|
||||||
|
|
||||||
await verifyKeyValueForOrigin('key', 'aaa', location.origin);
|
|
||||||
|
|
||||||
await deleteKeyForOrigin('key', location.origin);
|
|
||||||
}, 'Test for batchUpdate() with a batch lock in a Protected Audience Worklet context');
|
|
Reference in New Issue
Block a user