first_party_sets_access_delegate.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/first_party_sets/first_party_sets_access_delegate.h"
  5. #include <utility>
  6. #include "base/metrics/histogram_functions.h"
  7. #include "base/stl_util.h"
  8. #include "base/time/time.h"
  9. #include "net/base/schemeful_site.h"
  10. #include "net/cookies/first_party_set_metadata.h"
  11. namespace network {
  12. namespace {
  13. bool IsEnabled(const mojom::FirstPartySetsAccessDelegateParamsPtr& params) {
  14. return params.is_null() || params->enabled;
  15. }
  16. } // namespace
  17. FirstPartySetsAccessDelegate::FirstPartySetsAccessDelegate(
  18. mojo::PendingReceiver<mojom::FirstPartySetsAccessDelegate> receiver,
  19. mojom::FirstPartySetsAccessDelegateParamsPtr params,
  20. FirstPartySetsManager* const manager)
  21. : manager_(manager),
  22. context_config_(net::FirstPartySetsContextConfig(IsEnabled(params))),
  23. pending_queries_(
  24. IsEnabled(params) && receiver.is_valid() && manager_->is_enabled()
  25. ? std::make_unique<base::circular_deque<base::OnceClosure>>()
  26. : nullptr) {
  27. if (receiver.is_valid())
  28. receiver_.Bind(std::move(receiver));
  29. }
  30. FirstPartySetsAccessDelegate::~FirstPartySetsAccessDelegate() = default;
  31. void FirstPartySetsAccessDelegate::NotifyReady(
  32. mojom::FirstPartySetsReadyEventPtr ready_event) {
  33. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  34. context_config_.SetCustomizations(ready_event->customizations);
  35. InvokePendingQueries();
  36. }
  37. absl::optional<net::FirstPartySetMetadata>
  38. FirstPartySetsAccessDelegate::ComputeMetadata(
  39. const net::SchemefulSite& site,
  40. const net::SchemefulSite* top_frame_site,
  41. const std::set<net::SchemefulSite>& party_context,
  42. base::OnceCallback<void(net::FirstPartySetMetadata)> callback) {
  43. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  44. if (!context_config_.is_enabled()) {
  45. return {net::FirstPartySetMetadata()};
  46. }
  47. if (pending_queries_) {
  48. // base::Unretained() is safe because `this` owns `pending_queries_` and
  49. // `pending_queries_` will not run the enqueued callbacks after `this` is
  50. // destroyed.
  51. EnqueuePendingQuery(base::BindOnce(
  52. &FirstPartySetsAccessDelegate::ComputeMetadataAndInvoke,
  53. base::Unretained(this), site, base::OptionalFromPtr(top_frame_site),
  54. party_context, std::move(callback)));
  55. return absl::nullopt;
  56. }
  57. return manager_->ComputeMetadata(site, top_frame_site, party_context,
  58. context_config_, std::move(callback));
  59. }
  60. absl::optional<FirstPartySetsAccessDelegate::OwnersResult>
  61. FirstPartySetsAccessDelegate::FindOwners(
  62. const base::flat_set<net::SchemefulSite>& sites,
  63. base::OnceCallback<void(FirstPartySetsAccessDelegate::OwnersResult)>
  64. callback) {
  65. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  66. if (!context_config_.is_enabled())
  67. return {{}};
  68. if (pending_queries_) {
  69. // base::Unretained() is safe because `this` owns `pending_queries_` and
  70. // `pending_queries_` will not run the enqueued callbacks after `this` is
  71. // destroyed.
  72. EnqueuePendingQuery(
  73. base::BindOnce(&FirstPartySetsAccessDelegate::FindOwnersAndInvoke,
  74. base::Unretained(this), sites, std::move(callback)));
  75. return absl::nullopt;
  76. }
  77. return manager_->FindOwners(sites, context_config_, std::move(callback));
  78. }
  79. void FirstPartySetsAccessDelegate::ComputeMetadataAndInvoke(
  80. const net::SchemefulSite& site,
  81. const absl::optional<net::SchemefulSite> top_frame_site,
  82. const std::set<net::SchemefulSite>& party_context,
  83. base::OnceCallback<void(net::FirstPartySetMetadata)> callback) const {
  84. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  85. DCHECK(context_config_.is_enabled());
  86. std::pair<base::OnceCallback<void(net::FirstPartySetMetadata)>,
  87. base::OnceCallback<void(net::FirstPartySetMetadata)>>
  88. callbacks = base::SplitOnceCallback(std::move(callback));
  89. absl::optional<net::FirstPartySetMetadata> sync_result =
  90. manager_->ComputeMetadata(site, base::OptionalOrNullptr(top_frame_site),
  91. party_context, context_config_,
  92. std::move(callbacks.first));
  93. if (sync_result.has_value())
  94. std::move(callbacks.second).Run(std::move(sync_result.value()));
  95. }
  96. void FirstPartySetsAccessDelegate::FindOwnersAndInvoke(
  97. const base::flat_set<net::SchemefulSite>& sites,
  98. base::OnceCallback<void(FirstPartySetsAccessDelegate::OwnersResult)>
  99. callback) const {
  100. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  101. DCHECK(context_config_.is_enabled());
  102. std::pair<
  103. base::OnceCallback<void(FirstPartySetsAccessDelegate::OwnersResult)>,
  104. base::OnceCallback<void(FirstPartySetsAccessDelegate::OwnersResult)>>
  105. callbacks = base::SplitOnceCallback(std::move(callback));
  106. absl::optional<FirstPartySetsAccessDelegate::OwnersResult> sync_result =
  107. manager_->FindOwners(sites, context_config_, std::move(callbacks.first));
  108. if (sync_result.has_value())
  109. std::move(callbacks.second).Run(sync_result.value());
  110. }
  111. void FirstPartySetsAccessDelegate::InvokePendingQueries() {
  112. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  113. UmaHistogramTimes(
  114. "Cookie.FirstPartySets.InitializationDuration."
  115. "ContextReadyToServeQueries2",
  116. construction_timer_.Elapsed());
  117. base::UmaHistogramCounts10000(
  118. "Cookie.FirstPartySets.ContextDelayedQueriesCount",
  119. pending_queries_ ? pending_queries_->size() : 0);
  120. base::UmaHistogramTimes("Cookie.FirstPartySets.ContextMostDelayedQueryDelta",
  121. first_async_query_timer_.has_value()
  122. ? first_async_query_timer_->Elapsed()
  123. : base::TimeDelta());
  124. if (!pending_queries_)
  125. return;
  126. while (!pending_queries_->empty()) {
  127. base::OnceClosure query_task = std::move(pending_queries_->front());
  128. pending_queries_->pop_front();
  129. std::move(query_task).Run();
  130. }
  131. pending_queries_ = nullptr;
  132. }
  133. void FirstPartySetsAccessDelegate::EnqueuePendingQuery(
  134. base::OnceClosure run_query) {
  135. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  136. DCHECK(pending_queries_);
  137. if (!first_async_query_timer_.has_value())
  138. first_async_query_timer_ = {base::ElapsedTimer()};
  139. pending_queries_->push_back(std::move(run_query));
  140. }
  141. } // namespace network