[Browsing Data Model] Report access for Attribution Reporting
Propagates the topmost ancestor of the target frame to allow the BDM to access PageSpecificContentSettings in the Chrome client whenever a source or trigger is accessed. Bug: 1412085 Change-Id: Ifb3d711c749aac069f4ec1188ec20d88f263580b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4221460 Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Mariam Ali <alimariam@google.com> Reviewed-by: Christian Dullweber <dullweber@chromium.org> Reviewed-by: Andrew Paseltiner <apaseltiner@chromium.org> Commit-Queue: Thomas Quintanilla <tquintanilla@chromium.org> Reviewed-by: Nan Lin <linnan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1103324}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
07c661b991
commit
d1b3c03758
chrome/browser
content
browser
attribution_reporting
attribution_data_host_manager.hattribution_data_host_manager_impl.ccattribution_data_host_manager_impl.hattribution_data_host_manager_impl_unittest.ccattribution_host.ccattribution_host_unittest.ccattribution_internals_browsertest.ccattribution_internals_handler_impl.ccattribution_manager.hattribution_manager_impl.ccattribution_manager_impl.hattribution_manager_impl_unittest.ccattribution_simulator.ccattribution_test_utils.h
storage_partition_impl_unittest.ccpublic
@ -19,6 +19,7 @@
|
||||
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
|
||||
#include "components/services/storage/public/mojom/storage_usage_info.mojom.h"
|
||||
#include "components/services/storage/shared_storage/shared_storage_manager.h"
|
||||
#include "content/public/browser/attribution_data_model.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
@ -373,3 +374,51 @@ IN_PROC_BROWSER_TEST_F(BrowsingDataModelBrowserTest,
|
||||
{BrowsingDataModel::StorageType::kInterestGroup,
|
||||
/*storage_size=*/0, /*cookie_count=*/0}}});
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BrowsingDataModelBrowserTest,
|
||||
AttributionReportingAccessReportedCorrectly) {
|
||||
const GURL kTestCases[] = {
|
||||
https_test_server()->GetURL(
|
||||
"a.test", "/attribution_reporting/register_source_headers.html"),
|
||||
https_test_server()->GetURL(
|
||||
"a.test", "/attribution_reporting/register_trigger_headers.html")};
|
||||
|
||||
for (const auto& register_url : kTestCases) {
|
||||
// Navigate to test page.
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url()));
|
||||
auto* content_settings =
|
||||
content_settings::PageSpecificContentSettings::GetForFrame(
|
||||
web_contents()->GetPrimaryMainFrame());
|
||||
|
||||
// Validate that the allowed browsing data model is empty.
|
||||
auto* allowed_browsing_data_model =
|
||||
content_settings->allowed_browsing_data_model();
|
||||
ValidateBrowsingDataEntries(allowed_browsing_data_model, {});
|
||||
|
||||
// Register a source.
|
||||
ASSERT_TRUE(ExecJs(web_contents(), content::JsReplace(R"(
|
||||
const img = document.createElement('img');
|
||||
img.attributionSrc = $1;)",
|
||||
register_url))
|
||||
);
|
||||
|
||||
while (std::distance(allowed_browsing_data_model->begin(),
|
||||
allowed_browsing_data_model->end()) != 1) {
|
||||
base::RunLoop run_loop;
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
|
||||
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Validate that an attribution reporting datakey is reported to the
|
||||
// browsing data model.
|
||||
url::Origin testOrigin = https_test_server()->GetOrigin(kTestHost);
|
||||
content::AttributionDataModel::DataKey data_key{testOrigin};
|
||||
ValidateBrowsingDataEntries(
|
||||
allowed_browsing_data_model,
|
||||
{{kTestHost,
|
||||
data_key,
|
||||
{BrowsingDataModel::StorageType::kAttributionReporting,
|
||||
/*storage_size=*/0, /*cookie_count=*/0}}});
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +269,7 @@
|
||||
#include "components/translate/core/common/translate_switches.h"
|
||||
#include "components/variations/variations_associated_data.h"
|
||||
#include "components/variations/variations_switches.h"
|
||||
#include "content/public/browser/attribution_data_model.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "content/public/browser/browser_child_process_host.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
@ -3286,6 +3287,7 @@ bool ChromeContentBrowserClient::IsInterestGroupAPIAllowed(
|
||||
bool ChromeContentBrowserClient::IsAttributionReportingOperationAllowed(
|
||||
content::BrowserContext* browser_context,
|
||||
AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* source_origin,
|
||||
const url::Origin* destination_origin,
|
||||
const url::Origin* reporting_origin) {
|
||||
@ -3297,13 +3299,37 @@ bool ChromeContentBrowserClient::IsAttributionReportingOperationAllowed(
|
||||
return false;
|
||||
|
||||
switch (operation) {
|
||||
case AttributionReportingOperation::kSource:
|
||||
case AttributionReportingOperation::kSource: {
|
||||
DCHECK(source_origin);
|
||||
DCHECK(reporting_origin);
|
||||
bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed(
|
||||
*source_origin, *reporting_origin);
|
||||
if (rfh) {
|
||||
content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
|
||||
rfh, content::AttributionDataModel::DataKey(*reporting_origin),
|
||||
BrowsingDataModel::StorageType::kAttributionReporting,
|
||||
/*blocked=*/!allowed);
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
case AttributionReportingOperation::kSourceVerboseDebugReport:
|
||||
DCHECK(source_origin);
|
||||
DCHECK(reporting_origin);
|
||||
return privacy_sandbox_settings->IsAttributionReportingAllowed(
|
||||
*source_origin, *reporting_origin);
|
||||
case AttributionReportingOperation::kTrigger:
|
||||
case AttributionReportingOperation::kTrigger: {
|
||||
DCHECK(destination_origin);
|
||||
DCHECK(reporting_origin);
|
||||
bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed(
|
||||
*destination_origin, *reporting_origin);
|
||||
if (rfh) {
|
||||
content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
|
||||
rfh, content::AttributionDataModel::DataKey(*reporting_origin),
|
||||
BrowsingDataModel::StorageType::kAttributionReporting,
|
||||
/*blocked=*/!allowed);
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
case AttributionReportingOperation::kTriggerVerboseDebugReport:
|
||||
DCHECK(destination_origin);
|
||||
DCHECK(reporting_origin);
|
||||
|
@ -313,6 +313,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
|
||||
bool IsAttributionReportingOperationAllowed(
|
||||
content::BrowserContext* browser_context,
|
||||
AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* impression_origin,
|
||||
const url::Origin* conversion_origin,
|
||||
const url::Origin* reporting_origin) override;
|
||||
|
@ -32,6 +32,7 @@ class Origin;
|
||||
namespace content {
|
||||
|
||||
struct AttributionInputEvent;
|
||||
struct GlobalRenderFrameHostId;
|
||||
|
||||
// Interface responsible for coordinating `AttributionDataHost`s received from
|
||||
// the renderer.
|
||||
@ -41,12 +42,14 @@ class AttributionDataHostManager {
|
||||
|
||||
// Registers a new data host with the browser process for the given context
|
||||
// origin. This is only called for events which are not associated with a
|
||||
// navigation.
|
||||
// navigation. Passes the topmost ancestor of the initiator render frame for
|
||||
// obtaining the page access report.
|
||||
virtual void RegisterDataHost(
|
||||
mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host,
|
||||
attribution_reporting::SuitableOrigin context_origin,
|
||||
bool is_within_fenced_frame,
|
||||
attribution_reporting::mojom::RegistrationType) = 0;
|
||||
attribution_reporting::mojom::RegistrationType,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Registers a new data host which is associated with a navigation. The
|
||||
// context origin will be provided at a later time in
|
||||
@ -60,7 +63,8 @@ class AttributionDataHostManager {
|
||||
|
||||
// Notifies the manager that an attribution enabled navigation has registered
|
||||
// a source header. May be called multiple times for the same navigation.
|
||||
// Important: `header_value` is untrusted.
|
||||
// Important: `header_value` is untrusted. Passes the topmost ancestor of the
|
||||
// initiator render frame for obtaining the page access report.
|
||||
virtual void NotifyNavigationRedirectRegistration(
|
||||
const blink::AttributionSrcToken& attribution_src_token,
|
||||
std::string header_value,
|
||||
@ -68,16 +72,19 @@ class AttributionDataHostManager {
|
||||
const attribution_reporting::SuitableOrigin& source_origin,
|
||||
AttributionInputEvent input_event,
|
||||
blink::mojom::AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) = 0;
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Notifies the manager that we have received a navigation for a given data
|
||||
// host. This may arrive before or after the attribution configuration is
|
||||
// available for a given data host.
|
||||
// available for a given data host. Passes the topmost ancestor of the
|
||||
// initiator render frame for obtaining the page access report.
|
||||
virtual void NotifyNavigationForDataHost(
|
||||
const blink::AttributionSrcToken& attribution_src_token,
|
||||
const attribution_reporting::SuitableOrigin& source_origin,
|
||||
blink::mojom::AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) = 0;
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Notifies the manager that a navigation failed and should no longer be
|
||||
// tracked. The navigation was associated with a data host if
|
||||
@ -94,12 +101,14 @@ class AttributionDataHostManager {
|
||||
// for reportEvent or for an automatic beacon and should be tracked.
|
||||
// The actual beacon may be sent after the navigation finished or after the
|
||||
// RFHI was destroyed, therefore we need to store the information for later
|
||||
// use.
|
||||
// use. Passes the topmost ancestor of the initiator render frame for
|
||||
// obtaining the page access report.
|
||||
virtual void NotifyFencedFrameReportingBeaconStarted(
|
||||
BeaconId beacon_id,
|
||||
attribution_reporting::SuitableOrigin source_origin,
|
||||
bool is_within_fenced_frame,
|
||||
absl::optional<AttributionInputEvent> input_event) = 0;
|
||||
absl::optional<AttributionInputEvent> input_event,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Notifies the manager that a beacon has been sent.
|
||||
virtual void NotifyFencedFrameReportingBeaconSent(BeaconId beacon_id) = 0;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "content/browser/attribution_reporting/attribution_source_type.h"
|
||||
#include "content/browser/attribution_reporting/attribution_trigger.h"
|
||||
#include "content/browser/attribution_reporting/storable_source.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "net/base/schemeful_site.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "services/network/public/cpp/trigger_attestation.h"
|
||||
@ -111,13 +112,15 @@ class AttributionDataHostManagerImpl::ReceiverContext {
|
||||
base::TimeTicks register_time,
|
||||
bool is_within_fenced_frame,
|
||||
absl::optional<AttributionInputEvent> input_event,
|
||||
absl::optional<AttributionNavigationType> nav_type)
|
||||
absl::optional<AttributionNavigationType> nav_type,
|
||||
GlobalRenderFrameHostId render_frame_id)
|
||||
: context_origin_(std::move(context_origin)),
|
||||
registration_type_(registration_type),
|
||||
register_time_(register_time),
|
||||
is_within_fenced_frame_(is_within_fenced_frame),
|
||||
input_event_(input_event),
|
||||
nav_type_(nav_type) {
|
||||
nav_type_(nav_type),
|
||||
render_frame_id_(render_frame_id) {
|
||||
DCHECK(!nav_type_ || registration_type_ == RegistrationType::kSource);
|
||||
}
|
||||
|
||||
@ -148,6 +151,8 @@ class AttributionDataHostManagerImpl::ReceiverContext {
|
||||
return nav_type_;
|
||||
}
|
||||
|
||||
GlobalRenderFrameHostId render_frame_id() const { return render_frame_id_; }
|
||||
|
||||
void IncrementNumDataRegistered() { ++num_data_registered_; }
|
||||
|
||||
private:
|
||||
@ -173,6 +178,10 @@ class AttributionDataHostManagerImpl::ReceiverContext {
|
||||
|
||||
// Logically const.
|
||||
absl::optional<AttributionNavigationType> nav_type_;
|
||||
|
||||
// The ID of the topmost render frame host.
|
||||
// Logically const.
|
||||
GlobalRenderFrameHostId render_frame_id_;
|
||||
};
|
||||
|
||||
struct AttributionDataHostManagerImpl::DelayedTrigger {
|
||||
@ -181,6 +190,8 @@ struct AttributionDataHostManagerImpl::DelayedTrigger {
|
||||
|
||||
AttributionTrigger trigger;
|
||||
|
||||
GlobalRenderFrameHostId render_frame_id;
|
||||
|
||||
base::TimeDelta TimeUntil() const {
|
||||
return delay_until - base::TimeTicks::Now();
|
||||
}
|
||||
@ -224,6 +235,8 @@ struct AttributionDataHostManagerImpl::NavigationRedirectSourceRegistrations {
|
||||
// Whether the navigation is initiated within a fenced frame. Will not
|
||||
// change over the course of the redirect chain.
|
||||
bool is_within_fenced_frame;
|
||||
|
||||
GlobalRenderFrameHostId render_frame_id;
|
||||
};
|
||||
|
||||
struct AttributionDataHostManagerImpl::BeaconSourceRegistrations {
|
||||
@ -255,6 +268,8 @@ struct AttributionDataHostManagerImpl::BeaconSourceRegistrations {
|
||||
|
||||
// Input event associated with the navigation.
|
||||
absl::optional<AttributionInputEvent> input_event;
|
||||
|
||||
GlobalRenderFrameHostId render_frame_id;
|
||||
};
|
||||
|
||||
AttributionDataHostManagerImpl::AttributionDataHostManagerImpl(
|
||||
@ -273,13 +288,14 @@ void AttributionDataHostManagerImpl::RegisterDataHost(
|
||||
mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host,
|
||||
SuitableOrigin context_origin,
|
||||
bool is_within_fenced_frame,
|
||||
RegistrationType registration_type) {
|
||||
RegistrationType registration_type,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
receivers_.Add(this, std::move(data_host),
|
||||
ReceiverContext(std::move(context_origin), registration_type,
|
||||
/*register_time=*/base::TimeTicks::Now(),
|
||||
is_within_fenced_frame,
|
||||
/*input_event=*/absl::nullopt,
|
||||
/*nav_type=*/absl::nullopt));
|
||||
/*nav_type=*/absl::nullopt, render_frame_id));
|
||||
|
||||
switch (registration_type) {
|
||||
case RegistrationType::kSourceOrTrigger:
|
||||
@ -318,7 +334,8 @@ void AttributionDataHostManagerImpl::NotifyNavigationRedirectRegistration(
|
||||
const SuitableOrigin& source_origin,
|
||||
AttributionInputEvent input_event,
|
||||
AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) {
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
// Avoid costly isolated JSON parsing below if the header is obviously
|
||||
// invalid.
|
||||
if (header_value.empty()) {
|
||||
@ -335,7 +352,8 @@ void AttributionDataHostManagerImpl::NotifyNavigationRedirectRegistration(
|
||||
.register_time = base::TimeTicks::Now(),
|
||||
.input_event = input_event,
|
||||
.nav_type = nav_type,
|
||||
.is_within_fenced_frame = is_within_fenced_frame});
|
||||
.is_within_fenced_frame = is_within_fenced_frame,
|
||||
.render_frame_id = render_frame_id});
|
||||
DCHECK(!it->second.navigation_complete);
|
||||
|
||||
// Treat ongoing redirect registrations within a chain as a data host for the
|
||||
@ -359,7 +377,8 @@ void AttributionDataHostManagerImpl::NotifyNavigationForDataHost(
|
||||
const blink::AttributionSrcToken& attribution_src_token,
|
||||
const SuitableOrigin& source_origin,
|
||||
AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) {
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
auto it = navigation_data_host_map_.find(attribution_src_token);
|
||||
|
||||
if (it != navigation_data_host_map_.end()) {
|
||||
@ -367,7 +386,7 @@ void AttributionDataHostManagerImpl::NotifyNavigationForDataHost(
|
||||
this, std::move(it->second.data_host),
|
||||
ReceiverContext(source_origin, RegistrationType::kSource,
|
||||
it->second.register_time, is_within_fenced_frame,
|
||||
it->second.input_event, nav_type));
|
||||
it->second.input_event, nav_type, render_frame_id));
|
||||
|
||||
navigation_data_host_map_.erase(it);
|
||||
RecordNavigationDataHostStatus(NavigationDataHostStatus::kProcessed);
|
||||
@ -445,7 +464,8 @@ void AttributionDataHostManagerImpl::NotifyNavigationSuccess(
|
||||
registrations.navigation_complete = true;
|
||||
|
||||
for (StorableSource& source : registrations.sources) {
|
||||
attribution_manager_->HandleSource(std::move(source));
|
||||
attribution_manager_->HandleSource(std::move(source),
|
||||
registrations.render_frame_id);
|
||||
}
|
||||
registrations.sources.clear();
|
||||
|
||||
@ -485,7 +505,8 @@ void AttributionDataHostManagerImpl::SourceDataAvailable(
|
||||
StorableSource(std::move(reporting_origin), std::move(data),
|
||||
/*source_time=*/base::Time::Now(),
|
||||
/*source_origin=*/context.context_origin(), source_type,
|
||||
context.is_within_fenced_frame()));
|
||||
context.is_within_fenced_frame()),
|
||||
context.render_frame_id());
|
||||
}
|
||||
|
||||
void AttributionDataHostManagerImpl::TriggerDataAvailable(
|
||||
@ -525,7 +546,8 @@ void AttributionDataHostManagerImpl::TriggerDataAvailable(
|
||||
if (data_hosts_in_source_mode_ == 0) {
|
||||
DCHECK(delayed_triggers_.empty());
|
||||
RecordTriggerQueueEvent(TriggerQueueEvent::kSkippedQueue);
|
||||
attribution_manager_->HandleTrigger(std::move(trigger));
|
||||
attribution_manager_->HandleTrigger(std::move(trigger),
|
||||
context.render_frame_id());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -548,6 +570,7 @@ void AttributionDataHostManagerImpl::TriggerDataAvailable(
|
||||
delayed_triggers_.emplace_back(DelayedTrigger{
|
||||
.delay_until = base::TimeTicks::Now() + delay,
|
||||
.trigger = std::move(trigger),
|
||||
.render_frame_id = context.render_frame_id(),
|
||||
});
|
||||
RecordTriggerQueueEvent(TriggerQueueEvent::kEnqueued);
|
||||
|
||||
@ -569,7 +592,8 @@ void AttributionDataHostManagerImpl::ProcessDelayedTrigger() {
|
||||
delayed_triggers_.pop_front();
|
||||
DCHECK_LE(delayed_trigger.delay_until, base::TimeTicks::Now());
|
||||
|
||||
attribution_manager_->HandleTrigger(std::move(delayed_trigger.trigger));
|
||||
attribution_manager_->HandleTrigger(std::move(delayed_trigger.trigger),
|
||||
delayed_trigger.render_frame_id);
|
||||
RecordTriggerQueueEvent(TriggerQueueEvent::kProcessedWithDelay);
|
||||
delayed_trigger.RecordDelay();
|
||||
|
||||
@ -638,7 +662,8 @@ void AttributionDataHostManagerImpl::OnSourceEligibleDataHostFinished(
|
||||
"synchronously to avoid blocking for too long.");
|
||||
|
||||
for (auto& delayed_trigger : delayed_triggers_) {
|
||||
attribution_manager_->HandleTrigger(std::move(delayed_trigger.trigger));
|
||||
attribution_manager_->HandleTrigger(std::move(delayed_trigger.trigger),
|
||||
delayed_trigger.render_frame_id);
|
||||
RecordTriggerQueueEvent(TriggerQueueEvent::kFlushed);
|
||||
delayed_trigger.RecordDelay();
|
||||
}
|
||||
@ -672,7 +697,8 @@ void AttributionDataHostManagerImpl::OnRedirectSourceParsed(
|
||||
base::UmaHistogramEnumeration(
|
||||
"Conversions.SourceRegistration.NavigationType.Foreground",
|
||||
registrations.nav_type);
|
||||
attribution_manager_->HandleSource(std::move(*source));
|
||||
attribution_manager_->HandleSource(std::move(*source),
|
||||
registrations.render_frame_id);
|
||||
}
|
||||
|
||||
if (registrations.pending_source_data == 0u &&
|
||||
@ -688,7 +714,8 @@ void AttributionDataHostManagerImpl::NotifyFencedFrameReportingBeaconStarted(
|
||||
BeaconId beacon_id,
|
||||
SuitableOrigin source_origin,
|
||||
bool is_within_fenced_frame,
|
||||
absl::optional<AttributionInputEvent> input_event) {
|
||||
absl::optional<AttributionInputEvent> input_event,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
bool is_navigation = absl::holds_alternative<NavigationBeaconId>(beacon_id);
|
||||
DCHECK_EQ(is_navigation, input_event.has_value());
|
||||
|
||||
@ -696,7 +723,8 @@ void AttributionDataHostManagerImpl::NotifyFencedFrameReportingBeaconStarted(
|
||||
beacon_id, BeaconSourceRegistrations{
|
||||
.source_origin = std::move(source_origin),
|
||||
.is_within_fenced_frame = is_within_fenced_frame,
|
||||
.input_event = input_event});
|
||||
.input_event = input_event,
|
||||
.render_frame_id = render_frame_id});
|
||||
|
||||
if (!inserted) {
|
||||
return;
|
||||
@ -795,7 +823,8 @@ void AttributionDataHostManagerImpl::OnBeaconSourceParsed(
|
||||
|
||||
if (source.has_value()) {
|
||||
if (registrations.navigation_complete.value_or(true)) {
|
||||
attribution_manager_->HandleSource(std::move(*source));
|
||||
attribution_manager_->HandleSource(std::move(*source),
|
||||
registrations.render_frame_id);
|
||||
} else {
|
||||
registrations.sources.push_back(std::move(*source));
|
||||
}
|
||||
|
@ -67,7 +67,8 @@ class CONTENT_EXPORT AttributionDataHostManagerImpl
|
||||
mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host,
|
||||
attribution_reporting::SuitableOrigin context_origin,
|
||||
bool is_within_fenced_frame,
|
||||
attribution_reporting::mojom::RegistrationType) override;
|
||||
attribution_reporting::mojom::RegistrationType,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
bool RegisterNavigationDataHost(
|
||||
mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host,
|
||||
const blink::AttributionSrcToken& attribution_src_token,
|
||||
@ -79,12 +80,14 @@ class CONTENT_EXPORT AttributionDataHostManagerImpl
|
||||
const attribution_reporting::SuitableOrigin& source_origin,
|
||||
AttributionInputEvent input_event,
|
||||
blink::mojom::AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) override;
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
void NotifyNavigationForDataHost(
|
||||
const blink::AttributionSrcToken& attribution_src_token,
|
||||
const attribution_reporting::SuitableOrigin& source_origin,
|
||||
blink::mojom::AttributionNavigationType nav_type,
|
||||
bool is_within_fenced_frame) override;
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
void NotifyNavigationFailure(
|
||||
const absl::optional<blink::AttributionSrcToken>& attribution_src_token,
|
||||
int64_t navigation_id) override;
|
||||
@ -93,7 +96,8 @@ class CONTENT_EXPORT AttributionDataHostManagerImpl
|
||||
BeaconId beacon_id,
|
||||
attribution_reporting::SuitableOrigin source_origin,
|
||||
bool is_within_fenced_frame,
|
||||
absl::optional<AttributionInputEvent> input_event) override;
|
||||
absl::optional<AttributionInputEvent> input_event,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
void NotifyFencedFrameReportingBeaconSent(BeaconId beacon_id) override;
|
||||
void NotifyFencedFrameReportingBeaconData(
|
||||
BeaconId beacon_id,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "content/browser/attribution_reporting/attribution_source_type.h"
|
||||
#include "content/browser/attribution_reporting/attribution_test_utils.h"
|
||||
#include "content/browser/attribution_reporting/attribution_trigger.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@ -83,6 +84,8 @@ constexpr char kTriggerDataHandleStatusMetric[] =
|
||||
constexpr char kRegisterSourceJson[] =
|
||||
R"json({"source_event_id":"5","destination":"https://destination.example"})json";
|
||||
|
||||
const GlobalRenderFrameHostId kFrameId = {0, 1};
|
||||
|
||||
struct ExpectedTriggerQueueEventCounts {
|
||||
base::HistogramBase::Count skipped_queue = 0;
|
||||
base::HistogramBase::Count dropped = 0;
|
||||
@ -160,18 +163,22 @@ TEST_F(AttributionDataHostManagerImplTest, SourceDataHost_SourceRegistered) {
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleSource(AllOf(
|
||||
SourceTypeIs(AttributionSourceType::kEvent), SourceEventIdIs(10),
|
||||
DestinationSiteIs(destination_site), ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin), SourcePriorityIs(20),
|
||||
SourceDebugKeyIs(789), AggregationKeysAre(aggregation_keys),
|
||||
SourceIsWithinFencedFrameIs(false), SourceDebugReportingIs(true))));
|
||||
HandleSource(
|
||||
AllOf(SourceTypeIs(AttributionSourceType::kEvent),
|
||||
SourceEventIdIs(10), DestinationSiteIs(destination_site),
|
||||
ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin), SourcePriorityIs(20),
|
||||
SourceDebugKeyIs(789), AggregationKeysAre(aggregation_keys),
|
||||
SourceIsWithinFencedFrameIs(false),
|
||||
SourceDebugReportingIs(true)),
|
||||
kFrameId));
|
||||
{
|
||||
RemoteDataHost data_host_remote{.task_environment =
|
||||
raw_ref(task_environment_)};
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(), page_origin,
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Milliseconds(1));
|
||||
|
||||
@ -222,7 +229,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
raw_ref(task_environment_)};
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(), page_origin,
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
SourceRegistration source_data(destination_site);
|
||||
data_host_remote.data_host->SourceDataAvailable(reporting_origin,
|
||||
@ -270,24 +278,27 @@ TEST_F(AttributionDataHostManagerImplTest, TriggerDataHost_TriggerRegistered) {
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(AttributionTriggerMatcherConfig(
|
||||
reporting_origin,
|
||||
TriggerRegistrationMatches(TriggerRegistrationMatcherConfig(
|
||||
filters, AttributionFilters(), Optional(789),
|
||||
EventTriggerDataListMatches(
|
||||
EventTriggerDataListMatcherConfig(ElementsAre(
|
||||
EventTriggerDataMatches(EventTriggerDataMatcherConfig(
|
||||
1, 2, Optional(3), event_trigger_data_filters,
|
||||
event_trigger_data_not_filters)),
|
||||
EventTriggerDataMatches(EventTriggerDataMatcherConfig(
|
||||
4, 5, Eq(absl::nullopt), AttributionFilters(),
|
||||
AttributionFilters()))))),
|
||||
Optional(123),
|
||||
/*debug_reporting=*/true,
|
||||
attribution_reporting::AggregatableTriggerDataList(),
|
||||
attribution_reporting::AggregatableValues(),
|
||||
::aggregation_service::mojom::AggregationCoordinator::kDefault)),
|
||||
destination_origin))));
|
||||
HandleTrigger(
|
||||
AttributionTriggerMatches(AttributionTriggerMatcherConfig(
|
||||
reporting_origin,
|
||||
TriggerRegistrationMatches(TriggerRegistrationMatcherConfig(
|
||||
filters, AttributionFilters(), Optional(789),
|
||||
EventTriggerDataListMatches(
|
||||
EventTriggerDataListMatcherConfig(ElementsAre(
|
||||
EventTriggerDataMatches(EventTriggerDataMatcherConfig(
|
||||
1, 2, Optional(3), event_trigger_data_filters,
|
||||
event_trigger_data_not_filters)),
|
||||
EventTriggerDataMatches(EventTriggerDataMatcherConfig(
|
||||
4, 5, Eq(absl::nullopt), AttributionFilters(),
|
||||
AttributionFilters()))))),
|
||||
Optional(123),
|
||||
/*debug_reporting=*/true,
|
||||
attribution_reporting::AggregatableTriggerDataList(),
|
||||
attribution_reporting::AggregatableValues(),
|
||||
::aggregation_service::mojom::AggregationCoordinator::
|
||||
kDefault)),
|
||||
destination_origin)),
|
||||
kFrameId));
|
||||
|
||||
{
|
||||
RemoteDataHost data_host_remote{.task_environment =
|
||||
@ -295,7 +306,7 @@ TEST_F(AttributionDataHostManagerImplTest, TriggerDataHost_TriggerRegistered) {
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(),
|
||||
destination_origin, /*is_within_fenced_frame=*/false,
|
||||
RegistrationType::kSourceOrTrigger);
|
||||
RegistrationType::kSourceOrTrigger, kFrameId);
|
||||
|
||||
TriggerRegistration trigger_data;
|
||||
trigger_data.debug_key = 789;
|
||||
@ -354,7 +365,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(),
|
||||
destination_origin, /*is_within_fenced_frame=*/false,
|
||||
RegistrationType::kSourceOrTrigger);
|
||||
RegistrationType::kSourceOrTrigger, kFrameId);
|
||||
|
||||
TriggerRegistration trigger_data;
|
||||
|
||||
@ -428,7 +439,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
raw_ref(task_environment_)};
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(), page_origin,
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
SourceRegistration source_data(destination_site);
|
||||
|
||||
@ -492,13 +504,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleSource(AllOf(
|
||||
SourceTypeIs(AttributionSourceType::kNavigation),
|
||||
SourceEventIdIs(10), DestinationSiteIs(destination_site),
|
||||
ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin), SourcePriorityIs(20),
|
||||
SourceDebugKeyIs(789), AggregationKeysAre(aggregation_keys),
|
||||
SourceIsWithinFencedFrameIs(false), SourceDebugReportingIs(true))));
|
||||
HandleSource(
|
||||
AllOf(SourceTypeIs(AttributionSourceType::kNavigation),
|
||||
SourceEventIdIs(10), DestinationSiteIs(destination_site),
|
||||
ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin), SourcePriorityIs(20),
|
||||
SourceDebugKeyIs(789), AggregationKeysAre(aggregation_keys),
|
||||
SourceIsWithinFencedFrameIs(false),
|
||||
SourceDebugReportingIs(true)),
|
||||
kFrameId));
|
||||
EXPECT_CALL(checkpoint, Call(1));
|
||||
EXPECT_CALL(mock_manager_, HandleSource);
|
||||
}
|
||||
@ -517,7 +531,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, page_origin,
|
||||
AttributionNavigationType::kContextMenu,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
SourceRegistration source_data(destination_site);
|
||||
source_data.source_event_id = 10;
|
||||
@ -569,7 +583,8 @@ TEST_F(AttributionDataHostManagerImplTest, NoSourceOrTrigger) {
|
||||
raw_ref(task_environment_)};
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.data_host.BindNewPipeAndPassReceiver(), page_origin,
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
}
|
||||
|
||||
histograms.ExpectTotalCount("Conversions.RegisteredSourcesPerDataHost", 0);
|
||||
@ -601,13 +616,14 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.data_host.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, registration_type);
|
||||
/*is_within_fenced_frame=*/false, registration_type, kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Milliseconds(1));
|
||||
|
||||
@ -652,13 +668,13 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote1.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kTrigger, kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote2;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote2.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kTrigger, kFrameId);
|
||||
|
||||
// Because there is no data host in source mode, this trigger should not be
|
||||
// delayed.
|
||||
@ -695,7 +711,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
// Because there is a connected data host in source mode, this trigger should
|
||||
// be delayed.
|
||||
@ -729,7 +746,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
|
||||
@ -738,7 +755,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, source_site, AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
}
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
@ -752,7 +769,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
data_host_manager_.NotifyNavigationFailure(attribution_src_token,
|
||||
/*navigation_id=*/0);
|
||||
|
||||
@ -762,7 +779,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationRedirectSource_ParsingFinishesBeforeAndAfterNav) {
|
||||
EXPECT_CALL(mock_manager_, HandleSource(SourceIsWithinFencedFrameIs(false)))
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(SourceIsWithinFencedFrameIs(false), kFrameId))
|
||||
.Times(2);
|
||||
|
||||
auto reporter = *SuitableOrigin::Deserialize("https://report.test");
|
||||
@ -772,18 +790,18 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, source_site, AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
@ -806,18 +824,18 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, "!!!invalid json", reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, source_site, AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
@ -846,13 +864,14 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
// Because there is a connected data host in source mode, this trigger should
|
||||
// be delayed.
|
||||
@ -896,17 +915,17 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
// Wait for parsing.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, source_site, AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
checkpoint.Call(1);
|
||||
|
||||
@ -914,7 +933,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
/*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
@ -945,16 +965,16 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
attribution_src_token, kRegisterSourceJson, reporter, source_site,
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
// Wait for parsing.
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, source_site, AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/false);
|
||||
/*is_within_fenced_frame=*/false, kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
checkpoint.Call(1);
|
||||
@ -963,7 +983,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
/*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
@ -983,13 +1004,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
source_data_host_remote.reset();
|
||||
|
||||
@ -1010,13 +1033,15 @@ TEST_F(AttributionDataHostManagerImplTest, TwoTriggerReceivers) {
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote1.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote2;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote2.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
auto reporting_origin = *SuitableOrigin::Deserialize("https://report.test");
|
||||
|
||||
@ -1063,7 +1088,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Milliseconds(1));
|
||||
|
||||
@ -1101,26 +1127,32 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
EXPECT_CALL(mock_manager_, HandleTrigger).Times(0);
|
||||
EXPECT_CALL(checkpoint, Call(1));
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin1))));
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin1)),
|
||||
kFrameId));
|
||||
EXPECT_CALL(checkpoint, Call(2));
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin2))));
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin2)),
|
||||
kFrameId));
|
||||
}
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> source_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
auto send_trigger = [&](const SuitableOrigin& reporting_origin) {
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
@ -1153,19 +1185,22 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
base::RunLoop loop;
|
||||
EXPECT_CALL(mock_manager_, HandleTrigger)
|
||||
.WillOnce([&](AttributionTrigger trigger) { loop.Quit(); });
|
||||
.WillOnce([&](AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id) { loop.Quit(); });
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> source_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
/*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
@ -1199,13 +1234,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
auto send_trigger = [&](const SuitableOrigin& reporting_origin) {
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
@ -1216,10 +1253,14 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
auto reporting_origin = *SuitableOrigin::Deserialize(
|
||||
base::StrCat({"https://report", base::NumberToString(i), ".test"}));
|
||||
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin))))
|
||||
.WillOnce([&](AttributionTrigger trigger) { barrier.Run(); });
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(
|
||||
AttributionTriggerMatcherConfig(reporting_origin)),
|
||||
kFrameId))
|
||||
.WillOnce(
|
||||
[&](AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id) { barrier.Run(); });
|
||||
|
||||
send_trigger(reporting_origin);
|
||||
}
|
||||
@ -1260,13 +1301,15 @@ TEST_F(AttributionDataHostManagerImplTest, SourceThenTrigger_TriggerDelayed) {
|
||||
data_host_manager_.RegisterDataHost(
|
||||
source_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page1.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
SourceRegistration source_data(
|
||||
net::SchemefulSite::Deserialize("https://dest.test"));
|
||||
@ -1303,7 +1346,8 @@ TEST_F(AttributionDataHostManagerImplTest, NavigationDataHostNotRegistered) {
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token,
|
||||
*SuitableOrigin::Deserialize("https://page.example"),
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false);
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false,
|
||||
kFrameId);
|
||||
|
||||
// kNotFound = 1.
|
||||
histograms.ExpectUniqueSample("Conversions.NavigationDataHostStatus2", 1, 1);
|
||||
@ -1323,7 +1367,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token, *SuitableOrigin::Deserialize("https://s.test"),
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false);
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false,
|
||||
kFrameId);
|
||||
|
||||
mojo::test::BadMessageObserver bad_message_observer;
|
||||
|
||||
@ -1341,7 +1386,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
DuplicateAttributionSrcToken_NotRegistered) {
|
||||
EXPECT_CALL(mock_manager_, HandleSource(SourceEventIdIs(1)));
|
||||
EXPECT_CALL(mock_manager_, HandleSource(SourceEventIdIs(1), kFrameId));
|
||||
|
||||
const blink::AttributionSrcToken attribution_src_token;
|
||||
|
||||
@ -1372,7 +1417,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token,
|
||||
*SuitableOrigin::Deserialize("https://page.example"),
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false);
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false,
|
||||
kFrameId);
|
||||
|
||||
auto reporting_origin =
|
||||
*SuitableOrigin::Deserialize("https://reporter.example");
|
||||
@ -1396,18 +1442,20 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
auto reporting_origin =
|
||||
*SuitableOrigin::Deserialize("https://reporter.example");
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleSource(AllOf(
|
||||
SourceTypeIs(AttributionSourceType::kEvent), SourceEventIdIs(10),
|
||||
DestinationSiteIs(destination_site), ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin),
|
||||
SourceIsWithinFencedFrameIs(true))));
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(AllOf(SourceTypeIs(AttributionSourceType::kEvent),
|
||||
SourceEventIdIs(10),
|
||||
DestinationSiteIs(destination_site),
|
||||
ImpressionOriginIs(page_origin),
|
||||
ReportingOriginIs(reporting_origin),
|
||||
SourceIsWithinFencedFrameIs(true)),
|
||||
kFrameId));
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.BindNewPipeAndPassReceiver(), page_origin,
|
||||
/*is_within_fenced_frame=*/true, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/true, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Milliseconds(1));
|
||||
|
||||
@ -1427,13 +1475,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleTrigger(AttributionTriggerMatches(AttributionTriggerMatcherConfig(
|
||||
reporting_origin, _, destination_origin,
|
||||
/*is_within_fenced_frame=*/true))));
|
||||
reporting_origin, _, destination_origin,
|
||||
/*is_within_fenced_frame=*/true)),
|
||||
kFrameId));
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
data_host_remote.BindNewPipeAndPassReceiver(), destination_origin,
|
||||
/*is_within_fenced_frame=*/true, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/true, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
data_host_remote->TriggerDataAvailable(
|
||||
reporting_origin, TriggerRegistration(), /*attestation=*/absl::nullopt);
|
||||
@ -1442,7 +1492,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationSourceWithinFencedFrame_SourceRegistered) {
|
||||
EXPECT_CALL(mock_manager_, HandleSource(SourceIsWithinFencedFrameIs(true)));
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(SourceIsWithinFencedFrameIs(true), kFrameId));
|
||||
|
||||
const blink::AttributionSrcToken attribution_src_token;
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote;
|
||||
@ -1454,7 +1505,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyNavigationForDataHost(
|
||||
attribution_src_token,
|
||||
/*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"),
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/true);
|
||||
AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/true,
|
||||
kFrameId);
|
||||
|
||||
data_host_remote->SourceDataAvailable(
|
||||
/*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
@ -1466,7 +1518,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationRedirectSourceWithinFencedFrame_SourceRegistered) {
|
||||
EXPECT_CALL(mock_manager_, HandleSource(SourceIsWithinFencedFrameIs(true)));
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(SourceIsWithinFencedFrameIs(true), kFrameId));
|
||||
|
||||
const blink::AttributionSrcToken attribution_src_token;
|
||||
data_host_manager_.NotifyNavigationRedirectRegistration(
|
||||
@ -1474,7 +1527,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
/*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
/*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"),
|
||||
AttributionInputEvent(), AttributionNavigationType::kAnchor,
|
||||
/*is_within_fenced_frame=*/true);
|
||||
/*is_within_fenced_frame=*/true, kFrameId);
|
||||
// Wait for parsing to finish.
|
||||
task_environment_.FastForwardBy(base::TimeDelta());
|
||||
}
|
||||
@ -1489,7 +1542,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, std::move(source_origin), /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1524,7 +1577,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, std::move(source_origin), /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1554,7 +1607,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleSource(AllOf(SourceTypeIs(AttributionSourceType::kNavigation),
|
||||
SourceIsWithinFencedFrameIs(false))))
|
||||
SourceIsWithinFencedFrameIs(false)),
|
||||
kFrameId))
|
||||
.Times(2);
|
||||
|
||||
auto reporting_origin = url::Origin::Create(GURL("https://report.test"));
|
||||
@ -1563,7 +1617,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, std::move(source_origin), /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1603,7 +1657,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, source_origin, /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1629,8 +1683,9 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
|
||||
TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconSource_DataReceivedBeforeAndAfterNav) {
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(SourceTypeIs(AttributionSourceType::kNavigation)))
|
||||
EXPECT_CALL(
|
||||
mock_manager_,
|
||||
HandleSource(SourceTypeIs(AttributionSourceType::kNavigation), kFrameId))
|
||||
.Times(2);
|
||||
|
||||
auto reporting_origin = url::Origin::Create(GURL("https://report.test"));
|
||||
@ -1639,7 +1694,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, std::move(source_origin), /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1671,7 +1726,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id,
|
||||
/*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"),
|
||||
/*is_within_fenced_frame=*/false, AttributionInputEvent());
|
||||
/*is_within_fenced_frame=*/false, AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1707,14 +1762,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id,
|
||||
/*source_origin=*/*SuitableOrigin::Deserialize("https://report.test"),
|
||||
/*is_within_fenced_frame=*/false, AttributionInputEvent());
|
||||
/*is_within_fenced_frame=*/false, AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote;
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
// Because there is a connected data host in source mode, this trigger should
|
||||
// be delayed.
|
||||
@ -1757,7 +1813,7 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
NavigationBeaconId navigation_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
navigation_id, std::move(source_origin), /*is_within_fenced_frame=*/false,
|
||||
AttributionInputEvent());
|
||||
AttributionInputEvent(), kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(navigation_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
@ -1782,7 +1838,8 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
data_host_manager_.RegisterDataHost(
|
||||
trigger_data_host_remote.BindNewPipeAndPassReceiver(),
|
||||
*SuitableOrigin::Deserialize("https://page2.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger);
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSourceOrTrigger,
|
||||
kFrameId);
|
||||
|
||||
trigger_data_host_remote->TriggerDataAvailable(
|
||||
*SuitableOrigin::Create(std::move(reporting_origin)),
|
||||
@ -1795,14 +1852,15 @@ TEST_F(AttributionDataHostManagerImplTest,
|
||||
TEST_F(AttributionDataHostManagerImplTest, EventBeaconSource_DataReceived) {
|
||||
EXPECT_CALL(mock_manager_,
|
||||
HandleSource(AllOf(SourceTypeIs(AttributionSourceType::kEvent),
|
||||
SourceIsWithinFencedFrameIs(true))));
|
||||
SourceIsWithinFencedFrameIs(true)),
|
||||
kFrameId));
|
||||
|
||||
EventBeaconId event_id(123);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconStarted(
|
||||
event_id,
|
||||
/*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"),
|
||||
/*is_within_fenced_frame=*/true,
|
||||
/*input_event=*/absl::nullopt);
|
||||
/*input_event=*/absl::nullopt, kFrameId);
|
||||
data_host_manager_.NotifyFencedFrameReportingBeaconSent(event_id);
|
||||
|
||||
auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "content/browser/renderer_host/render_frame_host_impl.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
@ -80,6 +81,7 @@ struct AttributionHost::NavigationInfo {
|
||||
SuitableOrigin source_origin;
|
||||
AttributionInputEvent input_event;
|
||||
bool is_within_fenced_frame;
|
||||
GlobalRenderFrameHostId initiator_root_frame_id;
|
||||
};
|
||||
|
||||
AttributionHost::AttributionHost(WebContents* web_contents)
|
||||
@ -137,6 +139,10 @@ void AttributionHost::DidStartNavigation(NavigationHandle* navigation_handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderFrameHostImpl* initiator_root_frame =
|
||||
initiator_frame_host->GetOutermostMainFrame();
|
||||
DCHECK(initiator_root_frame);
|
||||
|
||||
// Look up the initiator root's origin which will be used as the impression
|
||||
// origin. This works because we won't update the origin for the initiator RFH
|
||||
// until we receive confirmation from the renderer that it has committed.
|
||||
@ -145,8 +151,7 @@ void AttributionHost::DidStartNavigation(NavigationHandle* navigation_handle) {
|
||||
// processed after a navigation commit in the initiator RFH, so reading the
|
||||
// origin off is safe at the start of the navigation.
|
||||
absl::optional<SuitableOrigin> initiator_root_frame_origin =
|
||||
SuitableOrigin::Create(initiator_frame_host->GetOutermostMainFrame()
|
||||
->GetLastCommittedOrigin());
|
||||
SuitableOrigin::Create(initiator_root_frame->GetLastCommittedOrigin());
|
||||
|
||||
if (!initiator_root_frame_origin) {
|
||||
return;
|
||||
@ -154,14 +159,16 @@ void AttributionHost::DidStartNavigation(NavigationHandle* navigation_handle) {
|
||||
|
||||
navigation_info_map_.emplace(
|
||||
navigation_handle->GetNavigationId(),
|
||||
NavigationInfo{.source_origin = std::move(*initiator_root_frame_origin),
|
||||
.input_event = AttributionHost::FromWebContents(
|
||||
WebContents::FromRenderFrameHost(
|
||||
initiator_frame_host))
|
||||
->GetMostRecentNavigationInputEvent(),
|
||||
NavigationInfo{
|
||||
.source_origin = std::move(*initiator_root_frame_origin),
|
||||
.input_event =
|
||||
AttributionHost::FromWebContents(
|
||||
WebContents::FromRenderFrameHost(initiator_frame_host))
|
||||
->GetMostRecentNavigationInputEvent(),
|
||||
|
||||
.is_within_fenced_frame =
|
||||
initiator_frame_host->IsNestedWithinFencedFrame()});
|
||||
.is_within_fenced_frame =
|
||||
initiator_frame_host->IsNestedWithinFencedFrame(),
|
||||
.initiator_root_frame_id = initiator_root_frame->GetGlobalId()});
|
||||
}
|
||||
|
||||
void AttributionHost::DidRedirectNavigation(
|
||||
@ -213,7 +220,7 @@ void AttributionHost::DidRedirectNavigation(
|
||||
navigation_handle->GetImpression()->attribution_src_token,
|
||||
std::move(source_header), std::move(*reporting_origin),
|
||||
it->second.source_origin, it->second.input_event, impression->nav_type,
|
||||
it->second.is_within_fenced_frame);
|
||||
it->second.is_within_fenced_frame, it->second.initiator_root_frame_id);
|
||||
}
|
||||
|
||||
void AttributionHost::DidFinishNavigation(NavigationHandle* navigation_handle) {
|
||||
@ -282,7 +289,8 @@ void AttributionHost::DidFinishNavigation(NavigationHandle* navigation_handle) {
|
||||
|
||||
data_host_manager->NotifyNavigationForDataHost(
|
||||
impression->attribution_src_token, source_origin, impression->nav_type,
|
||||
navigation_info.is_within_fenced_frame);
|
||||
navigation_info.is_within_fenced_frame,
|
||||
navigation_info.initiator_root_frame_id);
|
||||
}
|
||||
|
||||
void AttributionHost::MaybeNotifyFailedSourceNavigation(
|
||||
@ -376,10 +384,18 @@ void AttributionHost::RegisterDataHost(
|
||||
return;
|
||||
}
|
||||
|
||||
RenderFrameHostImpl* render_frame_host =
|
||||
static_cast<RenderFrameHostImpl*>(receivers_.GetCurrentTargetFrame());
|
||||
DCHECK(render_frame_host);
|
||||
|
||||
RenderFrameHostImpl* root_frame_host =
|
||||
render_frame_host->GetOutermostMainFrame();
|
||||
DCHECK(root_frame_host);
|
||||
|
||||
data_host_manager->RegisterDataHost(
|
||||
std::move(data_host), std::move(*top_frame_origin),
|
||||
receivers_.GetCurrentTargetFrame()->IsNestedWithinFencedFrame(),
|
||||
registration_type);
|
||||
render_frame_host->IsNestedWithinFencedFrame(), registration_type,
|
||||
root_frame_host->GetGlobalId());
|
||||
}
|
||||
|
||||
void AttributionHost::RegisterNavigationDataHost(
|
||||
@ -446,9 +462,12 @@ void AttributionHost::NotifyFencedFrameReportingBeaconStarted(
|
||||
return;
|
||||
}
|
||||
|
||||
RenderFrameHostImpl* initiator_root_frame =
|
||||
initiator_frame_host->GetOutermostMainFrame();
|
||||
DCHECK(initiator_root_frame);
|
||||
|
||||
absl::optional<SuitableOrigin> initiator_root_frame_origin =
|
||||
SuitableOrigin::Create(initiator_frame_host->GetOutermostMainFrame()
|
||||
->GetLastCommittedOrigin());
|
||||
SuitableOrigin::Create(initiator_root_frame->GetLastCommittedOrigin());
|
||||
|
||||
if (!initiator_root_frame_origin) {
|
||||
return;
|
||||
@ -463,7 +482,8 @@ void AttributionHost::NotifyFencedFrameReportingBeaconStarted(
|
||||
|
||||
data_host_manager->NotifyFencedFrameReportingBeaconStarted(
|
||||
beacon_id, std::move(*initiator_root_frame_origin),
|
||||
initiator_frame_host->IsNestedWithinFencedFrame(), input_event);
|
||||
initiator_frame_host->IsNestedWithinFencedFrame(), input_event,
|
||||
initiator_root_frame->GetGlobalId());
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(AttributionHost);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "content/browser/storage_partition_impl.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/test/test_renderer_host.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "content/test/navigation_simulator_impl.h"
|
||||
@ -72,7 +73,8 @@ class MockDataHostManager : public AttributionDataHostManager {
|
||||
(mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host,
|
||||
SuitableOrigin context_origin,
|
||||
bool is_within_fenced_frame,
|
||||
RegistrationType),
|
||||
RegistrationType,
|
||||
GlobalRenderFrameHostId),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(
|
||||
@ -91,7 +93,8 @@ class MockDataHostManager : public AttributionDataHostManager {
|
||||
const SuitableOrigin& source_origin,
|
||||
AttributionInputEvent input_event,
|
||||
AttributionNavigationType,
|
||||
bool is_within_fenced_frame),
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
@ -99,7 +102,8 @@ class MockDataHostManager : public AttributionDataHostManager {
|
||||
(const blink::AttributionSrcToken& attribution_src_token,
|
||||
const SuitableOrigin& source_origin,
|
||||
AttributionNavigationType,
|
||||
bool is_within_fenced_frame),
|
||||
bool is_within_fenced_frame,
|
||||
GlobalRenderFrameHostId),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(
|
||||
@ -119,7 +123,8 @@ class MockDataHostManager : public AttributionDataHostManager {
|
||||
(BeaconId beacon_id,
|
||||
SuitableOrigin source_origin,
|
||||
bool is_within_fenced_frame,
|
||||
absl::optional<AttributionInputEvent> input_event),
|
||||
absl::optional<AttributionInputEvent> input_event,
|
||||
GlobalRenderFrameHostId),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
@ -211,7 +216,7 @@ TEST_F(AttributionHostTest, ValidAttributionSrc_ForwardedToManager) {
|
||||
impression.attribution_src_token,
|
||||
*SuitableOrigin::Deserialize("https://secure_impression.com"),
|
||||
impression.nav_type,
|
||||
/*is_within_fenced_frame=*/false));
|
||||
/*is_within_fenced_frame=*/false, main_rfh()->GetGlobalId()));
|
||||
|
||||
contents()->NavigateAndCommit(GURL("https://secure_impression.com"));
|
||||
auto navigation = NavigationSimulatorImpl::CreateRendererInitiated(
|
||||
@ -399,10 +404,11 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
::testing::ValuesIn(kOriginTrustworthyChecksTestCases));
|
||||
|
||||
TEST_F(AttributionHostTest, DataHost_RegisteredWithContext) {
|
||||
EXPECT_CALL(*mock_data_host_manager(),
|
||||
RegisterDataHost(
|
||||
_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSource));
|
||||
EXPECT_CALL(
|
||||
*mock_data_host_manager(),
|
||||
RegisterDataHost(_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/false,
|
||||
RegistrationType::kSource, main_rfh()->GetGlobalId()));
|
||||
|
||||
contents()->NavigateAndCommit(GURL("https://top.example"));
|
||||
SetCurrentTargetFrameForTesting(main_rfh());
|
||||
@ -484,10 +490,11 @@ TEST_F(AttributionHostTest, DuplicateAttributionSrcToken_BadMessage) {
|
||||
}
|
||||
|
||||
TEST_F(AttributionHostTest, DataHostInSubframe_ContextIsOutermostFrame) {
|
||||
EXPECT_CALL(*mock_data_host_manager(),
|
||||
RegisterDataHost(
|
||||
_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/false, RegistrationType::kSource));
|
||||
EXPECT_CALL(
|
||||
*mock_data_host_manager(),
|
||||
RegisterDataHost(_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/false,
|
||||
RegistrationType::kSource, main_rfh()->GetGlobalId()));
|
||||
|
||||
contents()->NavigateAndCommit(GURL("https://top.example"));
|
||||
|
||||
@ -539,10 +546,11 @@ TEST_F(AttributionHostTest,
|
||||
}
|
||||
|
||||
TEST_F(AttributionHostTest, DataHost_RegisteredWithFencedFrame) {
|
||||
EXPECT_CALL(*mock_data_host_manager(),
|
||||
RegisterDataHost(
|
||||
_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/true, RegistrationType::kSource));
|
||||
EXPECT_CALL(
|
||||
*mock_data_host_manager(),
|
||||
RegisterDataHost(_, *SuitableOrigin::Deserialize("https://top.example"),
|
||||
/*is_within_fenced_frame=*/true,
|
||||
RegistrationType::kSource, main_rfh()->GetGlobalId()));
|
||||
|
||||
contents()->NavigateAndCommit(GURL("https://top.example"));
|
||||
RenderFrameHost* fenced_frame =
|
||||
@ -580,19 +588,20 @@ TEST_F(AttributionHostTest, NotifyFencedFrameReportingBeaconStarted) {
|
||||
NavigationBeaconId navigation_id(123);
|
||||
|
||||
for (const auto& test_case : kTestCases) {
|
||||
contents()->NavigateAndCommit(GURL(test_case.source_origin));
|
||||
if (test_case.expected_valid) {
|
||||
EXPECT_CALL(*mock_data_host_manager(),
|
||||
NotifyFencedFrameReportingBeaconStarted(
|
||||
VariantWith<NavigationBeaconId>(navigation_id),
|
||||
*SuitableOrigin::Deserialize(test_case.source_origin),
|
||||
/*is_within_fenced_frame=*/true, _));
|
||||
EXPECT_CALL(
|
||||
*mock_data_host_manager(),
|
||||
NotifyFencedFrameReportingBeaconStarted(
|
||||
VariantWith<NavigationBeaconId>(navigation_id),
|
||||
*SuitableOrigin::Deserialize(test_case.source_origin),
|
||||
/*is_within_fenced_frame=*/true, _, main_rfh()->GetGlobalId()));
|
||||
} else {
|
||||
EXPECT_CALL(*mock_data_host_manager(),
|
||||
NotifyFencedFrameReportingBeaconStarted)
|
||||
.Times(0);
|
||||
}
|
||||
|
||||
contents()->NavigateAndCommit(GURL(test_case.source_origin));
|
||||
RenderFrameHost* fenced_frame =
|
||||
RenderFrameHostTester::For(main_rfh())
|
||||
->AppendFencedFrame(blink::mojom::FencedFrameMode::kOpaqueAds);
|
||||
|
@ -206,7 +206,7 @@ IN_PROC_BROWSER_TEST_F(AttributionInternalsWebUiBrowserTest,
|
||||
EXPECT_CALL(browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kAny,
|
||||
IsNull(), IsNull(), IsNull()))
|
||||
_, IsNull(), IsNull(), IsNull()))
|
||||
.WillRepeatedly(Return(false));
|
||||
|
||||
ASSERT_TRUE(NavigateToURL(shell(), GURL(kAttributionInternalsUrl)));
|
||||
|
@ -243,8 +243,8 @@ void AttributionInternalsHandlerImpl::IsAttributionReportingEnabled(
|
||||
GetContentClient()->browser()->IsAttributionReportingOperationAllowed(
|
||||
contents->GetBrowserContext(),
|
||||
ContentBrowserClient::AttributionReportingOperation::kAny,
|
||||
/*source_origin=*/nullptr, /*destination_origin=*/nullptr,
|
||||
/*reporting_origin=*/nullptr);
|
||||
/*rfh=*/nullptr, /*source_origin=*/nullptr,
|
||||
/*destination_origin=*/nullptr, /*reporting_origin=*/nullptr);
|
||||
bool debug_mode = base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kAttributionReportingDebugMode);
|
||||
std::move(callback).Run(attribution_reporting_enabled, debug_mode);
|
||||
|
@ -33,6 +33,8 @@ class StorableSource;
|
||||
class StoredSource;
|
||||
class WebContents;
|
||||
|
||||
struct GlobalRenderFrameHostId;
|
||||
|
||||
// Interface that mediates data flow between the network, storage layer, and
|
||||
// blink.
|
||||
class AttributionManager : public AttributionDataModel {
|
||||
@ -52,11 +54,13 @@ class AttributionManager : public AttributionDataModel {
|
||||
|
||||
// Persists the given |source| to storage. Called when a navigation
|
||||
// originating from a source tag finishes.
|
||||
virtual void HandleSource(StorableSource source) = 0;
|
||||
virtual void HandleSource(StorableSource source,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Process a newly registered trigger. Will create and log any new
|
||||
// reports to storage.
|
||||
virtual void HandleTrigger(AttributionTrigger trigger) = 0;
|
||||
virtual void HandleTrigger(AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id) = 0;
|
||||
|
||||
// Get all sources that are currently stored in this partition. Used for
|
||||
// populating WebUI.
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browsing_data_filter_builder.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
@ -303,12 +305,13 @@ std::unique_ptr<AttributionStorageDelegate> MakeStorageDelegate() {
|
||||
bool IsOperationAllowed(
|
||||
StoragePartitionImpl* storage_partition,
|
||||
ContentBrowserClient::AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* source_origin,
|
||||
const url::Origin* destination_origin,
|
||||
const url::Origin* reporting_origin) {
|
||||
DCHECK(storage_partition);
|
||||
return GetContentClient()->browser()->IsAttributionReportingOperationAllowed(
|
||||
storage_partition->browser_context(), operation, source_origin,
|
||||
storage_partition->browser_context(), operation, rfh, source_origin,
|
||||
destination_origin, reporting_origin);
|
||||
}
|
||||
|
||||
@ -316,6 +319,11 @@ bool g_run_in_memory = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
struct AttributionManagerImpl::SourceOrTriggerRFH {
|
||||
SourceOrTrigger source_or_trigger;
|
||||
GlobalRenderFrameHostId rfh_id;
|
||||
};
|
||||
|
||||
BASE_FEATURE(kAttributionVerboseDebugReporting,
|
||||
"AttributionVerboseDebugReporting",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
@ -382,7 +390,8 @@ bool AttributionManagerImpl::IsReportAllowed(
|
||||
return IsOperationAllowed(
|
||||
storage_partition_.get(),
|
||||
ContentBrowserClient::AttributionReportingOperation::kReport,
|
||||
&*common_info.source_origin(), &*report.attribution_info().context_origin,
|
||||
/*rfh=*/nullptr, &*common_info.source_origin(),
|
||||
&*report.attribution_info().context_origin,
|
||||
&*common_info.reporting_origin());
|
||||
}
|
||||
|
||||
@ -502,8 +511,11 @@ AttributionDataHostManager* AttributionManagerImpl::GetDataHostManager() {
|
||||
return data_host_manager_.get();
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::HandleSource(StorableSource source) {
|
||||
MaybeEnqueueEvent(std::move(source));
|
||||
void AttributionManagerImpl::HandleSource(
|
||||
StorableSource source,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
MaybeEnqueueEvent(SourceOrTriggerRFH{.source_or_trigger = std::move(source),
|
||||
.rfh_id = render_frame_id});
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::StoreSource(
|
||||
@ -535,8 +547,11 @@ void AttributionManagerImpl::OnSourceStored(
|
||||
MaybeSendVerboseDebugReport(source, is_debug_cookie_set, result);
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::HandleTrigger(AttributionTrigger trigger) {
|
||||
MaybeEnqueueEvent(std::move(trigger));
|
||||
void AttributionManagerImpl::HandleTrigger(
|
||||
AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id) {
|
||||
MaybeEnqueueEvent(SourceOrTriggerRFH{.source_or_trigger = std::move(trigger),
|
||||
.rfh_id = render_frame_id});
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::StoreTrigger(
|
||||
@ -550,7 +565,7 @@ void AttributionManagerImpl::StoreTrigger(
|
||||
cleared_debug_key, is_debug_cookie_set));
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::MaybeEnqueueEvent(SourceOrTrigger event) {
|
||||
void AttributionManagerImpl::MaybeEnqueueEvent(SourceOrTriggerRFH event) {
|
||||
const size_t size_before_push = pending_events_.size();
|
||||
|
||||
// Avoid unbounded memory growth with adversarial input.
|
||||
@ -591,7 +606,7 @@ void AttributionManagerImpl::ProcessEvents() {
|
||||
: nullptr;
|
||||
},
|
||||
},
|
||||
pending_events_.front());
|
||||
pending_events_.front().source_or_trigger);
|
||||
if (cookie_origin) {
|
||||
cookie_checker_->IsDebugCookieSet(
|
||||
*cookie_origin,
|
||||
@ -614,7 +629,7 @@ void AttributionManagerImpl::ProcessEvents() {
|
||||
void AttributionManagerImpl::ProcessNextEvent(bool is_debug_cookie_set) {
|
||||
DCHECK(!pending_events_.empty());
|
||||
|
||||
SourceOrTrigger event = std::move(pending_events_.front());
|
||||
SourceOrTriggerRFH event = std::move(pending_events_.front());
|
||||
pending_events_.pop_front();
|
||||
|
||||
absl::visit(
|
||||
@ -625,6 +640,7 @@ void AttributionManagerImpl::ProcessNextEvent(bool is_debug_cookie_set) {
|
||||
bool allowed = IsOperationAllowed(
|
||||
this->storage_partition_.get(),
|
||||
ContentBrowserClient::AttributionReportingOperation::kSource,
|
||||
RenderFrameHost::FromID(event.rfh_id),
|
||||
&*common_info.source_origin(),
|
||||
/*destination_origin=*/nullptr,
|
||||
&*common_info.reporting_origin());
|
||||
@ -654,6 +670,7 @@ void AttributionManagerImpl::ProcessNextEvent(bool is_debug_cookie_set) {
|
||||
bool allowed = IsOperationAllowed(
|
||||
this->storage_partition_.get(),
|
||||
ContentBrowserClient::AttributionReportingOperation::kTrigger,
|
||||
RenderFrameHost::FromID(event.rfh_id),
|
||||
/*source_origin=*/nullptr, &*trigger.destination_origin(),
|
||||
&*trigger.reporting_origin());
|
||||
RecordRegisterConversionAllowed(allowed);
|
||||
@ -679,7 +696,7 @@ void AttributionManagerImpl::ProcessNextEvent(bool is_debug_cookie_set) {
|
||||
is_debug_cookie_set);
|
||||
},
|
||||
},
|
||||
std::move(event));
|
||||
std::move(event.source_or_trigger));
|
||||
}
|
||||
|
||||
void AttributionManagerImpl::OnReportStored(
|
||||
@ -1083,6 +1100,7 @@ void AttributionManagerImpl::MaybeSendVerboseDebugReport(
|
||||
if (!IsOperationAllowed(storage_partition_.get(),
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kSourceVerboseDebugReport,
|
||||
/*rfh=*/nullptr,
|
||||
&*source.common_info().source_origin(),
|
||||
/*destination_origin=*/nullptr,
|
||||
&*source.common_info().reporting_origin())) {
|
||||
@ -1109,6 +1127,7 @@ void AttributionManagerImpl::MaybeSendVerboseDebugReport(
|
||||
if (!IsOperationAllowed(storage_partition_.get(),
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kTriggerVerboseDebugReport,
|
||||
/*rfh=*/nullptr,
|
||||
/*source_origin=*/nullptr,
|
||||
&*trigger.destination_origin(),
|
||||
&*trigger.reporting_origin())) {
|
||||
|
@ -58,6 +58,7 @@ class CreateReportResult;
|
||||
class StoragePartitionImpl;
|
||||
class StoredSource;
|
||||
|
||||
struct GlobalRenderFrameHostId;
|
||||
struct SendResult;
|
||||
|
||||
CONTENT_EXPORT BASE_DECLARE_FEATURE(kAttributionVerboseDebugReporting);
|
||||
@ -140,8 +141,10 @@ class CONTENT_EXPORT AttributionManagerImpl : public AttributionManager {
|
||||
void AddObserver(AttributionObserver* observer) override;
|
||||
void RemoveObserver(AttributionObserver* observer) override;
|
||||
AttributionDataHostManager* GetDataHostManager() override;
|
||||
void HandleSource(StorableSource source) override;
|
||||
void HandleTrigger(AttributionTrigger trigger) override;
|
||||
void HandleSource(StorableSource source,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
void HandleTrigger(AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id) override;
|
||||
void GetActiveSourcesForWebUI(
|
||||
base::OnceCallback<void(std::vector<StoredSource>)> callback) override;
|
||||
void GetPendingReportsForInternalUse(
|
||||
@ -182,6 +185,8 @@ class CONTENT_EXPORT AttributionManagerImpl : public AttributionManager {
|
||||
using ReportSentCallback = AttributionReportSender::ReportSentCallback;
|
||||
using SourceOrTrigger = absl::variant<StorableSource, AttributionTrigger>;
|
||||
|
||||
struct SourceOrTriggerRFH;
|
||||
|
||||
AttributionManagerImpl(
|
||||
StoragePartitionImpl* storage_partition,
|
||||
const base::FilePath& user_data_directory,
|
||||
@ -193,7 +198,7 @@ class CONTENT_EXPORT AttributionManagerImpl : public AttributionManager {
|
||||
std::unique_ptr<AttributionDataHostManager> data_host_manager,
|
||||
scoped_refptr<base::UpdateableSequencedTaskRunner> storage_task_runner);
|
||||
|
||||
void MaybeEnqueueEvent(SourceOrTrigger event);
|
||||
void MaybeEnqueueEvent(SourceOrTriggerRFH event);
|
||||
void ProcessEvents();
|
||||
void ProcessNextEvent(bool is_debug_cookie_set);
|
||||
void StoreSource(StorableSource source,
|
||||
@ -269,7 +274,7 @@ class CONTENT_EXPORT AttributionManagerImpl : public AttributionManager {
|
||||
// the simulator currently depends on. We may be able to loosen this
|
||||
// requirement in the future so that there are conceptually separate queues
|
||||
// per <source origin, destination origin, reporting origin>.
|
||||
base::circular_deque<SourceOrTrigger> pending_events_;
|
||||
base::circular_deque<SourceOrTriggerRFH> pending_events_;
|
||||
|
||||
// Controls the maximum size of `pending_events_` to avoid unbounded memory
|
||||
// growth with adversarial input.
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "content/browser/storage_partition_impl.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browsing_data_filter_builder.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "content/public/test/test_browser_context.h"
|
||||
@ -94,6 +95,7 @@ using ReportSentCallback =
|
||||
::content::AttributionReportSender::ReportSentCallback;
|
||||
|
||||
constexpr size_t kMaxPendingEvents = 5;
|
||||
const GlobalRenderFrameHostId kFrameId = {0, 1};
|
||||
|
||||
constexpr AttributionStorageDelegate::OfflineReportDelayConfig
|
||||
kDefaultOfflineReportDelay{
|
||||
@ -316,7 +318,7 @@ class AttributionManagerImplTest : public testing::Test {
|
||||
TEST_F(AttributionManagerImplTest, ImpressionRegistered_ReturnedToWebUI) {
|
||||
SourceBuilder builder;
|
||||
builder.SetExpiry(kImpressionExpiry).SetSourceEventId(100);
|
||||
attribution_manager_->HandleSource(builder.Build());
|
||||
attribution_manager_->HandleSource(builder.Build(), kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredSources(),
|
||||
ElementsAre(CommonSourceInfoIs(builder.BuildCommonInfo())));
|
||||
@ -326,7 +328,8 @@ TEST_F(AttributionManagerImplTest, ExpiredImpression_NotReturnedToWebUI) {
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetSourceEventId(100)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.FastForwardBy(2 * kImpressionExpiry);
|
||||
|
||||
EXPECT_THAT(StoredSources(), IsEmpty());
|
||||
@ -335,10 +338,10 @@ TEST_F(AttributionManagerImplTest, ExpiredImpression_NotReturnedToWebUI) {
|
||||
TEST_F(AttributionManagerImplTest, ImpressionConverted_ReportReturnedToWebUI) {
|
||||
SourceBuilder builder;
|
||||
builder.SetExpiry(kImpressionExpiry).SetSourceEventId(100);
|
||||
attribution_manager_->HandleSource(builder.Build());
|
||||
attribution_manager_->HandleSource(builder.Build(), kFrameId);
|
||||
|
||||
auto conversion = TriggerBuilder().SetTriggerData(5).Build();
|
||||
attribution_manager_->HandleTrigger(conversion);
|
||||
attribution_manager_->HandleTrigger(conversion, kFrameId);
|
||||
|
||||
AttributionReport expected_report =
|
||||
ReportBuilder(AttributionInfoBuilder(
|
||||
@ -373,8 +376,8 @@ TEST_F(AttributionManagerImplTest, ImpressionConverted_ReportSent) {
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
// Make sure the report is not sent earlier than its report time.
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow -
|
||||
@ -425,23 +428,26 @@ TEST_F(AttributionManagerImplTest,
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_a)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build(), kFrameId);
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_b)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build(), kFrameId);
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_c)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_c).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_c).Build(), kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredReports(), SizeIs(3));
|
||||
|
||||
@ -489,18 +495,20 @@ TEST_F(AttributionManagerImplTest,
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_a)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build(), kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Microseconds(1));
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_b)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build(), kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredReports(), SizeIs(2));
|
||||
|
||||
@ -529,8 +537,8 @@ TEST_F(AttributionManagerImplTest, SenderStillHandlingReport_NotSentAgain) {
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
checkpoint.Call(1);
|
||||
@ -562,8 +570,8 @@ TEST_F(AttributionManagerImplTest,
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
@ -615,17 +623,19 @@ TEST_F(AttributionManagerImplTest, RetryLogicOverridesGetReportTimer) {
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_a)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_a).Build(), kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(base::Minutes(10));
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetReportingOrigin(origin_b)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build());
|
||||
TriggerBuilder().SetReportingOrigin(origin_b).Build(), kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredReports(), SizeIs(2));
|
||||
|
||||
@ -646,8 +656,8 @@ TEST_F(AttributionManagerImplTest,
|
||||
base::HistogramTester histograms;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
|
||||
MockAttributionObserver observer;
|
||||
@ -706,8 +716,8 @@ TEST_F(AttributionManagerImplTest, QueuedReportAlwaysFails_StopsSending) {
|
||||
SendResult::Status::kTransientFailure)));
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow -
|
||||
base::Milliseconds(1));
|
||||
@ -740,8 +750,8 @@ TEST_F(AttributionManagerImplTest, QueuedReportAlwaysFails_StopsSending) {
|
||||
|
||||
TEST_F(AttributionManagerImplTest, ReportExpiredAtStartup_Sent) {
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
ShutdownManager();
|
||||
|
||||
@ -761,8 +771,8 @@ TEST_F(AttributionManagerImplTest, ReportExpiredAtStartup_Sent) {
|
||||
TEST_F(AttributionManagerImplTest, ReportSent_Deleted) {
|
||||
base::HistogramTester histograms;
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
EXPECT_CALL(*report_sender_, SendReport(_, /*is_debug_report=*/false, _))
|
||||
.WillOnce(InvokeReportSentCallback(SendResult::Status::kSent));
|
||||
@ -798,25 +808,29 @@ TEST_F(AttributionManagerImplTest, QueuedReportSent_ObserversNotified) {
|
||||
/*is_debug_report=*/false, _));
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetSourceEventId(1).SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetSourceEventId(1).SetExpiry(kImpressionExpiry).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
// This one should be stored, as its status is `kDropped`.
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetSourceEventId(2).SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetSourceEventId(2).SetExpiry(kImpressionExpiry).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetSourceEventId(3).SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetSourceEventId(3).SetExpiry(kImpressionExpiry).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
// This one shouldn't be stored, as it will be retried.
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetSourceEventId(4).SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetSourceEventId(4).SetExpiry(kImpressionExpiry).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
task_environment_.FastForwardBy(kFirstReportingWindow);
|
||||
|
||||
// kSent = 0.
|
||||
@ -886,14 +900,14 @@ TEST_F(AttributionManagerImplTest, TriggerHandled_ObserversNotified) {
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
|
||||
// `kNavigation` sources can have 3 reports, so none of these should result in
|
||||
// a dropped report.
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetPriority(i).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(i).Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(i));
|
||||
}
|
||||
|
||||
@ -901,8 +915,8 @@ TEST_F(AttributionManagerImplTest, TriggerHandled_ObserversNotified) {
|
||||
|
||||
{
|
||||
// This should replace the report with priority 1.
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetPriority(4).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(4).Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(3));
|
||||
}
|
||||
|
||||
@ -912,7 +926,7 @@ TEST_F(AttributionManagerImplTest, TriggerHandled_ObserversNotified) {
|
||||
// This should be dropped, as it has a lower priority than all stored
|
||||
// reports.
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetPriority(-5).Build());
|
||||
TriggerBuilder().SetPriority(-5).Build(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(3));
|
||||
}
|
||||
|
||||
@ -920,10 +934,10 @@ TEST_F(AttributionManagerImplTest, TriggerHandled_ObserversNotified) {
|
||||
|
||||
{
|
||||
// These should replace the reports with priority 2 and 3.
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetPriority(5).Build());
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetPriority(6).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(5).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(6).Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(3));
|
||||
}
|
||||
}
|
||||
@ -934,8 +948,8 @@ TEST_F(AttributionManagerImplTest, ClearData) {
|
||||
for (bool match_url : {true, false}) {
|
||||
base::Time start = base::Time::Now();
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder(start).SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder(start).SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
base::RunLoop run_loop;
|
||||
attribution_manager_->ClearData(
|
||||
@ -963,8 +977,8 @@ TEST_F(AttributionManagerImplTest, ConversionsSentFromUI_ReportedImmediately) {
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
std::vector<AttributionReport> reports = StoredReports();
|
||||
EXPECT_THAT(reports, SizeIs(1));
|
||||
|
||||
@ -998,9 +1012,9 @@ TEST_F(AttributionManagerImplTest,
|
||||
size_t callback_calls = 0;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
std::vector<AttributionReport> reports = StoredReports();
|
||||
EXPECT_THAT(reports, SizeIs(2));
|
||||
|
||||
@ -1031,8 +1045,8 @@ TEST_F(AttributionManagerImplTest, ExpiredReportsAtStartup_Delayed) {
|
||||
.Times(0);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
ShutdownManager();
|
||||
|
||||
@ -1061,8 +1075,8 @@ TEST_F(AttributionManagerImplTest,
|
||||
|
||||
// Create a report that will be reported at t= 2 days.
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
ShutdownManager();
|
||||
|
||||
@ -1086,11 +1100,12 @@ TEST_F(AttributionManagerImplTest, SessionOnlyOrigins_DataDeletedAtShutdown) {
|
||||
|
||||
mock_storage_policy_->AddSessionOnly(session_only_origin);
|
||||
|
||||
attribution_manager_->HandleSource(impression);
|
||||
attribution_manager_->HandleSource(impression, kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder()
|
||||
.SetReportingOrigin(impression.common_info().reporting_origin())
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
@ -1110,7 +1125,7 @@ TEST_F(AttributionManagerImplTest, SessionOnlyOrigins_DataDeletedAtShutdown) {
|
||||
// priority trigger.
|
||||
TEST_F(AttributionManagerImplTest, ConversionPrioritization_OneReportSent) {
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(base::Days(7)).Build());
|
||||
SourceBuilder().SetExpiry(base::Days(7)).Build(), kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
|
||||
Checkpoint checkpoint;
|
||||
@ -1125,9 +1140,12 @@ TEST_F(AttributionManagerImplTest, ConversionPrioritization_OneReportSent) {
|
||||
.Times(0);
|
||||
}
|
||||
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(3));
|
||||
|
||||
task_environment_.FastForwardBy(base::Days(7) - base::Minutes(30));
|
||||
@ -1135,13 +1153,14 @@ TEST_F(AttributionManagerImplTest, ConversionPrioritization_OneReportSent) {
|
||||
checkpoint.Call(1);
|
||||
|
||||
task_environment_.FastForwardBy(base::Minutes(5));
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(2).Build());
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(2).Build(),
|
||||
kFrameId);
|
||||
task_environment_.FastForwardBy(base::Hours(1));
|
||||
}
|
||||
|
||||
TEST_F(AttributionManagerImplTest, HandleTrigger_RecordsMetric) {
|
||||
base::HistogramTester histograms;
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), IsEmpty());
|
||||
histograms.ExpectUniqueSample(
|
||||
"Conversions.CreateReportStatus7",
|
||||
@ -1153,7 +1172,7 @@ TEST_F(AttributionManagerImplTest, HandleTrigger_RecordsMetric) {
|
||||
|
||||
TEST_F(AttributionManagerImplTest, HandleSource_RecordsMetric) {
|
||||
base::HistogramTester histograms;
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build());
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build(), kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
histograms.ExpectUniqueSample("Conversions.SourceStoredStatus2",
|
||||
StorableSource::Result::kSuccess, 1);
|
||||
@ -1161,8 +1180,8 @@ TEST_F(AttributionManagerImplTest, HandleSource_RecordsMetric) {
|
||||
|
||||
TEST_F(AttributionManagerImplTest, OnReportSent_NotifiesObservers) {
|
||||
base::HistogramTester histograms;
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
|
||||
MockAttributionObserver observer;
|
||||
@ -1208,16 +1227,17 @@ TEST_F(AttributionManagerImplTest, HandleSource_NotifiesObservers) {
|
||||
EXPECT_CALL(observer, OnReportsChanged).Times(0);
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(source);
|
||||
attribution_manager_->HandleSource(source, kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
checkpoint.Call(1);
|
||||
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
checkpoint.Call(2);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).SetSourceEventId(9).Build());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).SetSourceEventId(9).Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(2));
|
||||
}
|
||||
|
||||
@ -1270,14 +1290,14 @@ TEST_F(AttributionManagerImplTest, HandleTrigger_NotifiesObservers) {
|
||||
.Times(0);
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(source);
|
||||
attribution_manager_->HandleSource(source, kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
checkpoint.Call(1);
|
||||
|
||||
// Store the maximum number of reports for the source.
|
||||
for (size_t i = 1; i <= 3; i++) {
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
// i event-level reports and i aggregatable reports.
|
||||
EXPECT_THAT(StoredReports(), SizeIs(i * 2));
|
||||
}
|
||||
@ -1306,7 +1326,7 @@ TEST_F(AttributionManagerImplTest, HandleTrigger_NotifiesObservers) {
|
||||
// The next event-level report should cause the source to reach the
|
||||
// event-level attribution limit; the report itself shouldn't be stored as
|
||||
// we've already reached the maximum number of event-level reports per source.
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), IsEmpty());
|
||||
}
|
||||
|
||||
@ -1348,7 +1368,7 @@ TEST_F(AttributionManagerImplTest,
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kSource,
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kSource, _,
|
||||
Pointee(url::Origin::Create(GURL("https://impression.test/"))),
|
||||
IsNull(), Pointee(url::Origin::Create(GURL("https://report.test/")))))
|
||||
.WillOnce(Return(false));
|
||||
@ -1357,11 +1377,11 @@ TEST_F(AttributionManagerImplTest,
|
||||
_,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kSourceVerboseDebugReport,
|
||||
_, _, _))
|
||||
_, _, _, _))
|
||||
.WillOnce(Return(true));
|
||||
ScopedContentBrowserClientSetting setting(&browser_client);
|
||||
|
||||
attribution_manager_->HandleSource(source);
|
||||
attribution_manager_->HandleSource(source, kFrameId);
|
||||
EXPECT_THAT(StoredSources(), IsEmpty());
|
||||
|
||||
histograms.ExpectUniqueSample("Conversions.RegisterImpressionAllowed", false,
|
||||
@ -1399,12 +1419,12 @@ TEST_F(AttributionManagerImplTest,
|
||||
kSourceVerboseDebugReport,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kTriggerVerboseDebugReport),
|
||||
_, _, _))
|
||||
_, _, _, _))
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kTrigger,
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kTrigger, _,
|
||||
IsNull(),
|
||||
Pointee(url::Origin::Create(GURL("https://sub.conversion.test/"))),
|
||||
Pointee(url::Origin::Create(GURL("https://report.test/")))))
|
||||
@ -1412,10 +1432,10 @@ TEST_F(AttributionManagerImplTest,
|
||||
ScopedContentBrowserClientSetting setting(&browser_client);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
|
||||
attribution_manager_->HandleTrigger(trigger);
|
||||
attribution_manager_->HandleTrigger(trigger, kFrameId);
|
||||
EXPECT_THAT(StoredReports(), IsEmpty());
|
||||
|
||||
histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", false,
|
||||
@ -1434,12 +1454,12 @@ TEST_F(AttributionManagerImplTest, EmbedderDisallowsReporting_ReportNotSent) {
|
||||
kSourceVerboseDebugReport,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kTriggerVerboseDebugReport),
|
||||
_, _, _))
|
||||
_, _, _, _))
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kReport,
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kReport, _,
|
||||
Pointee(url::Origin::Create(GURL("https://impression.test/"))),
|
||||
Pointee(url::Origin::Create(GURL("https://sub.conversion.test/"))),
|
||||
Pointee(url::Origin::Create(GURL("https://report.test/")))))
|
||||
@ -1452,8 +1472,8 @@ TEST_F(AttributionManagerImplTest, EmbedderDisallowsReporting_ReportNotSent) {
|
||||
.Times(0);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
|
||||
MockAttributionObserver observer;
|
||||
@ -1493,12 +1513,12 @@ TEST_F(AttributionManagerImplTest,
|
||||
kSourceVerboseDebugReport,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kTriggerVerboseDebugReport),
|
||||
_, _, _))
|
||||
_, _, _, _))
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kReport,
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kReport, _,
|
||||
Pointee(source_origin), Pointee(destination_origin),
|
||||
Pointee(reporting_origin)))
|
||||
.WillOnce(Return(false));
|
||||
@ -1514,14 +1534,16 @@ TEST_F(AttributionManagerImplTest,
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugKey(123)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder()
|
||||
.SetDestinationOrigin(destination_origin)
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugKey(456)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
}
|
||||
@ -1538,8 +1560,8 @@ TEST_F(AttributionManagerImplTest, Offline_NoReportSent) {
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
|
||||
SetConnectionTypeAndWaitForObserversToBeNotified(
|
||||
@ -1568,8 +1590,8 @@ class AttributionManagerImplOnlineConnectionTypeTest
|
||||
TEST_F(AttributionManagerImplOnlineConnectionTypeTest,
|
||||
OnlineConnectionTypeChanges_ReportTimesNotAdjusted) {
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
EXPECT_THAT(StoredReports(), SizeIs(1));
|
||||
|
||||
// Deliberately avoid running tasks so that the connection change and time
|
||||
@ -1594,8 +1616,8 @@ TEST_F(AttributionManagerImplTest, TimeFromConversionToReportSendHistogram) {
|
||||
base::HistogramTester histograms;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
ReportSentCallback report_sent_callback;
|
||||
absl::optional<AttributionReport> sent_report;
|
||||
@ -1640,9 +1662,10 @@ TEST_F(AttributionManagerImplTest, SendReport_RecordsExtraReportDelay2) {
|
||||
attribution_manager_->HandleSource(TestAggregatableSourceProvider()
|
||||
.GetBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
|
||||
// Prevent the report from being sent until after its original report time.
|
||||
SetConnectionTypeAndWaitForObserversToBeNotified(
|
||||
@ -1670,9 +1693,10 @@ TEST_F(AttributionManagerImplTest, SendReport_RecordsSchedulerReportDelay) {
|
||||
attribution_manager_->HandleSource(TestAggregatableSourceProvider()
|
||||
.GetBuilder()
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredReports(), SizeIs(2));
|
||||
|
||||
@ -1693,8 +1717,8 @@ TEST_F(AttributionManagerImplTest, SendReportsFromWebUI_DoesNotRecordMetrics) {
|
||||
base::HistogramTester histograms;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(DefaultTrigger(), kFrameId);
|
||||
|
||||
EXPECT_CALL(*report_sender_, SendReport(_, /*is_debug_report=*/false, _));
|
||||
|
||||
@ -1735,7 +1759,7 @@ TEST_F(AttributionManagerImplFakeReportTest,
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build());
|
||||
SourceBuilder().SetExpiry(kImpressionExpiry).Build(), kFrameId);
|
||||
|
||||
checkpoint.Call(1);
|
||||
task_environment_.FastForwardBy(base::Days(1));
|
||||
@ -1754,26 +1778,31 @@ TEST_F(AttributionManagerImplTest, RegistrationsHandledInOrder) {
|
||||
.SetDebugKey(11)
|
||||
.SetReportingOrigin(r1)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetTriggerData(2).SetReportingOrigin(r1).Build());
|
||||
TriggerBuilder().SetTriggerData(2).SetReportingOrigin(r1).Build(),
|
||||
kFrameId);
|
||||
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder()
|
||||
.SetTriggerData(3)
|
||||
.SetDebugKey(13)
|
||||
.SetReportingOrigin(r2)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetSourceEventId(4)
|
||||
.SetDebugKey(14)
|
||||
.SetReportingOrigin(r2)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetTriggerData(5).SetReportingOrigin(r2).Build());
|
||||
TriggerBuilder().SetTriggerData(5).SetReportingOrigin(r2).Build(),
|
||||
kFrameId);
|
||||
|
||||
ASSERT_THAT(StoredSources(), IsEmpty());
|
||||
ASSERT_THAT(StoredReports(), IsEmpty());
|
||||
@ -1857,7 +1886,8 @@ TEST_F(AttributionManagerImplTest, HandleSource_DebugKey) {
|
||||
*SuitableOrigin::Deserialize(test_case.reporting_origin))
|
||||
.SetDebugKey(test_case.input_debug_key)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredSources(),
|
||||
ElementsAre(SourceDebugKeyIs(test_case.expected_debug_key)))
|
||||
@ -1887,7 +1917,8 @@ TEST_F(AttributionManagerImplTest, HandleTrigger_DebugKey) {
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1)) << test_case.name;
|
||||
EXPECT_CALL(observer,
|
||||
@ -1896,7 +1927,8 @@ TEST_F(AttributionManagerImplTest, HandleTrigger_DebugKey) {
|
||||
TriggerBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugKey(test_case.input_debug_key)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
EXPECT_THAT(
|
||||
StoredReports(),
|
||||
ElementsAre(AllOf(ReportSourceIs(SourceDebugKeyIs(absl::nullopt)),
|
||||
@ -1942,7 +1974,8 @@ TEST_F(AttributionManagerImplTest, DebugReport_SentImmediately) {
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetExpiry(kImpressionExpiry)
|
||||
.SetDebugKey(test_case.source_debug_key)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1)) << test_case.name;
|
||||
|
||||
@ -1980,7 +2013,8 @@ TEST_F(AttributionManagerImplTest, DebugReport_SentImmediately) {
|
||||
DefaultAggregatableTriggerBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugKey(test_case.trigger_debug_key)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
// one event-level-report, one aggregatable report.
|
||||
EXPECT_THAT(StoredReports(), SizeIs(2)) << test_case.name;
|
||||
|
||||
@ -2006,7 +2040,7 @@ TEST_F(AttributionManagerImplTest,
|
||||
EXPECT_CALL(observer, OnSourceHandled(source, testing::Eq(absl::nullopt),
|
||||
StorableSource::Result::kSuccess));
|
||||
|
||||
attribution_manager_->HandleSource(source);
|
||||
attribution_manager_->HandleSource(source, kFrameId);
|
||||
EXPECT_THAT(StoredSources(), SizeIs(1));
|
||||
}
|
||||
|
||||
@ -2015,9 +2049,9 @@ TEST_F(AttributionManagerImplTest,
|
||||
base::HistogramTester histograms;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
TestAggregatableSourceProvider().GetBuilder().Build());
|
||||
TestAggregatableSourceProvider().GetBuilder().Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
|
||||
MockAttributionObserver observer;
|
||||
base::ScopedObservation<AttributionManager, AttributionObserver> observation(
|
||||
@ -2098,9 +2132,9 @@ TEST_F(AttributionManagerImplTest,
|
||||
base::HistogramTester histograms;
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
TestAggregatableSourceProvider().GetBuilder().Build());
|
||||
TestAggregatableSourceProvider().GetBuilder().Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
|
||||
MockAttributionObserver observer;
|
||||
base::ScopedObservation<AttributionManager, AttributionObserver> observation(
|
||||
@ -2159,9 +2193,9 @@ TEST_F(AttributionManagerImplTest, AggregationServiceDisabled_ReportNotSent) {
|
||||
ShutdownAggregationService();
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
TestAggregatableSourceProvider().GetBuilder().Build());
|
||||
TestAggregatableSourceProvider().GetBuilder().Build(), kFrameId);
|
||||
attribution_manager_->HandleTrigger(
|
||||
DefaultAggregatableTriggerBuilder().Build());
|
||||
DefaultAggregatableTriggerBuilder().Build(), kFrameId);
|
||||
|
||||
// Event-level report was sent.
|
||||
EXPECT_CALL(*report_sender_, SendReport(_, /*is_debug_report=*/false, _));
|
||||
@ -2207,7 +2241,8 @@ TEST_F(AttributionManagerImplTest, TooManyEventsInQueue) {
|
||||
|
||||
for (size_t i = 0; i <= kMaxPendingEvents; i++) {
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetDebugKey(i).SetExpiry(kImpressionExpiry).Build());
|
||||
SourceBuilder().SetDebugKey(i).SetExpiry(kImpressionExpiry).Build(),
|
||||
kFrameId);
|
||||
}
|
||||
|
||||
histograms.ExpectBucketCount("Conversions.EnqueueEventAllowed", true,
|
||||
@ -2242,7 +2277,7 @@ TEST_F(AttributionManagerImplTest, TriggerVerboseDebugReport_ReportSent) {
|
||||
|
||||
// Failed without debug reporting.
|
||||
attribution_manager_->HandleTrigger(
|
||||
TriggerBuilder().SetReportingOrigin(reporting_origin).Build());
|
||||
TriggerBuilder().SetReportingOrigin(reporting_origin).Build(), kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
// Trigger registered within a fenced frame failed with debug reporting, but
|
||||
@ -2251,7 +2286,8 @@ TEST_F(AttributionManagerImplTest, TriggerVerboseDebugReport_ReportSent) {
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.SetIsWithinFencedFrame(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
// Trigger registered outside a fenced frame tree failed with debug reporting
|
||||
@ -2260,7 +2296,8 @@ TEST_F(AttributionManagerImplTest, TriggerVerboseDebugReport_ReportSent) {
|
||||
TriggerBuilder()
|
||||
.SetReportingOrigin(*SuitableOrigin::Deserialize("https://r2.test"))
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
{
|
||||
@ -2274,7 +2311,8 @@ TEST_F(AttributionManagerImplTest, TriggerVerboseDebugReport_ReportSent) {
|
||||
TriggerBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
}
|
||||
|
||||
@ -2290,7 +2328,8 @@ TEST_F(AttributionManagerImplTest, TriggerVerboseDebugReport_ReportSent) {
|
||||
TriggerBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
}
|
||||
}
|
||||
@ -2307,7 +2346,7 @@ TEST_F(AttributionManagerImplTest,
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kTrigger, _,
|
||||
_, _))
|
||||
_, _, _))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
@ -2315,7 +2354,7 @@ TEST_F(AttributionManagerImplTest,
|
||||
_,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kTriggerVerboseDebugReport,
|
||||
IsNull(),
|
||||
_, IsNull(),
|
||||
Pointee(url::Origin::Create(GURL("https://sub.conversion.test/"))),
|
||||
Pointee(reporting_origin)))
|
||||
.WillOnce(Return(false));
|
||||
@ -2324,7 +2363,8 @@ TEST_F(AttributionManagerImplTest,
|
||||
attribution_manager_->HandleTrigger(TriggerBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
}
|
||||
|
||||
@ -2353,14 +2393,15 @@ TEST_F(AttributionManagerImplDebugReportTest, VerboseDebugReport_ReportSent) {
|
||||
});
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build());
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build(), kFrameId);
|
||||
|
||||
const auto destination_origin =
|
||||
*SuitableOrigin::Deserialize("https://d.test");
|
||||
|
||||
// Failed without debug reporting.
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetDestinationOrigin(destination_origin).Build());
|
||||
SourceBuilder().SetDestinationOrigin(destination_origin).Build(),
|
||||
kFrameId);
|
||||
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
@ -2373,7 +2414,8 @@ TEST_F(AttributionManagerImplDebugReportTest, VerboseDebugReport_ReportSent) {
|
||||
.SetDestinationOrigin(destination_origin)
|
||||
.SetIsWithinFencedFrame(true)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
@ -2390,7 +2432,8 @@ TEST_F(AttributionManagerImplDebugReportTest, VerboseDebugReport_ReportSent) {
|
||||
SourceBuilder()
|
||||
.SetDestinationOrigin(destination_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
@ -2409,7 +2452,8 @@ TEST_F(AttributionManagerImplDebugReportTest, VerboseDebugReport_ReportSent) {
|
||||
SourceBuilder()
|
||||
.SetDestinationOrigin(destination_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
@ -2432,7 +2476,7 @@ TEST_F(AttributionManagerImplDebugReportTest,
|
||||
browser_client,
|
||||
IsAttributionReportingOperationAllowed(
|
||||
_, ContentBrowserClient::AttributionReportingOperation::kSource, _, _,
|
||||
_))
|
||||
_, _))
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(
|
||||
browser_client,
|
||||
@ -2440,20 +2484,21 @@ TEST_F(AttributionManagerImplDebugReportTest,
|
||||
_,
|
||||
ContentBrowserClient::AttributionReportingOperation::
|
||||
kSourceVerboseDebugReport,
|
||||
Pointee(url::Origin::Create(GURL("https://impression.test/"))),
|
||||
_, Pointee(url::Origin::Create(GURL("https://impression.test/"))),
|
||||
IsNull(), Pointee(url::Origin::Create(GURL("https://report.test/")))))
|
||||
.WillRepeatedly(Return(false));
|
||||
ScopedContentBrowserClientSetting setting(&browser_client);
|
||||
|
||||
EXPECT_CALL(*report_sender_, SendReport(_, _)).Times(0);
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build());
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build(), kFrameId);
|
||||
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder()
|
||||
.SetDestinationOrigin(*SuitableOrigin::Deserialize("https://d.test"))
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
@ -2495,11 +2540,11 @@ TEST_F(AttributionManagerImplCookieBasedDebugReportTest,
|
||||
});
|
||||
}
|
||||
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build());
|
||||
attribution_manager_->HandleSource(SourceBuilder().Build(), kFrameId);
|
||||
|
||||
// Failed without debug reporting.
|
||||
attribution_manager_->HandleSource(
|
||||
SourceBuilder().SetReportingOrigin(reporting_origin).Build());
|
||||
SourceBuilder().SetReportingOrigin(reporting_origin).Build(), kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
// Source registered within a fenced frame failed with debug reporting, but
|
||||
@ -2508,7 +2553,8 @@ TEST_F(AttributionManagerImplCookieBasedDebugReportTest,
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.SetIsWithinFencedFrame(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
// Source registered outside a fenced frame failed with debug reporting but no
|
||||
@ -2517,7 +2563,8 @@ TEST_F(AttributionManagerImplCookieBasedDebugReportTest,
|
||||
SourceBuilder()
|
||||
.SetReportingOrigin(*SuitableOrigin::Deserialize("https://r2.test"))
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
checkpoint.Call(1);
|
||||
@ -2527,7 +2574,8 @@ TEST_F(AttributionManagerImplCookieBasedDebugReportTest,
|
||||
attribution_manager_->HandleSource(SourceBuilder()
|
||||
.SetReportingOrigin(reporting_origin)
|
||||
.SetDebugReporting(true)
|
||||
.Build());
|
||||
.Build(),
|
||||
kFrameId);
|
||||
task_environment_.RunUntilIdle();
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "content/browser/attribution_reporting/send_result.h"
|
||||
#include "content/browser/attribution_reporting/stored_source.h"
|
||||
#include "content/browser/storage_partition_impl.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "content/public/test/test_browser_context.h"
|
||||
@ -267,13 +268,14 @@ class AttributionEventHandler : public AttributionObserver {
|
||||
// For use with `absl::visit()`.
|
||||
void operator()(AttributionSource source) {
|
||||
fake_cookie_checker_->set_debug_cookie_set(source.debug_permission);
|
||||
manager_->HandleSource(std::move(source.source));
|
||||
manager_->HandleSource(std::move(source.source), GlobalRenderFrameHostId());
|
||||
}
|
||||
|
||||
// For use with `absl::visit()`.
|
||||
void operator()(AttributionTriggerAndTime trigger) {
|
||||
fake_cookie_checker_->set_debug_cookie_set(trigger.debug_permission);
|
||||
manager_->HandleTrigger(std::move(trigger.trigger));
|
||||
manager_->HandleTrigger(std::move(trigger.trigger),
|
||||
GlobalRenderFrameHostId());
|
||||
}
|
||||
|
||||
base::Value::Dict TakeOutput() {
|
||||
|
@ -98,6 +98,7 @@ class MockAttributionReportingContentBrowserClientBase : public SuperClass {
|
||||
IsAttributionReportingOperationAllowed,
|
||||
(content::BrowserContext * browser_context,
|
||||
ContentBrowserClient::AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* source_origin,
|
||||
const url::Origin* destination_origin,
|
||||
const url::Origin* reporting_origin),
|
||||
@ -258,9 +259,16 @@ class MockAttributionManager : public AttributionManager {
|
||||
~MockAttributionManager() override;
|
||||
|
||||
// AttributionManager:
|
||||
MOCK_METHOD(void, HandleSource, (StorableSource source), (override));
|
||||
MOCK_METHOD(void,
|
||||
HandleSource,
|
||||
(StorableSource source, GlobalRenderFrameHostId render_frame_id),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, HandleTrigger, (AttributionTrigger trigger), (override));
|
||||
MOCK_METHOD(void,
|
||||
HandleTrigger,
|
||||
(AttributionTrigger trigger,
|
||||
GlobalRenderFrameHostId render_frame_id),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
GetActiveSourcesForWebUI,
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/browsing_data_filter_builder.h"
|
||||
#include "content/public/browser/generated_code_cache_settings.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/browser/storage_usage_info.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
@ -1822,8 +1823,9 @@ TEST_F(StoragePartitionImplTest, ConversionsClearDataForOrigin) {
|
||||
|
||||
base::Time now = base::Time::Now();
|
||||
auto source = SourceBuilder(now).SetExpiry(base::Days(2)).Build();
|
||||
attribution_manager->HandleSource(source);
|
||||
attribution_manager->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager->HandleSource(source, GlobalRenderFrameHostId());
|
||||
attribution_manager->HandleTrigger(DefaultTrigger(),
|
||||
GlobalRenderFrameHostId());
|
||||
|
||||
base::RunLoop run_loop;
|
||||
partition->ClearData(
|
||||
@ -1843,8 +1845,9 @@ TEST_F(StoragePartitionImplTest, ConversionsClearDataWrongMask) {
|
||||
|
||||
base::Time now = base::Time::Now();
|
||||
auto source = SourceBuilder(now).SetExpiry(base::Days(2)).Build();
|
||||
attribution_manager->HandleSource(source);
|
||||
attribution_manager->HandleTrigger(DefaultTrigger());
|
||||
attribution_manager->HandleSource(source, GlobalRenderFrameHostId());
|
||||
attribution_manager->HandleTrigger(DefaultTrigger(),
|
||||
GlobalRenderFrameHostId());
|
||||
|
||||
EXPECT_FALSE(GetAttributionReportsForTesting(attribution_manager).empty());
|
||||
|
||||
@ -1873,7 +1876,7 @@ TEST_F(StoragePartitionImplTest, ConversionsClearAllData) {
|
||||
.SetReportingOrigin(origin)
|
||||
.SetDestinationOrigin(origin)
|
||||
.Build();
|
||||
attribution_manager->HandleSource(source);
|
||||
attribution_manager->HandleSource(source, GlobalRenderFrameHostId());
|
||||
}
|
||||
base::RunLoop run_loop;
|
||||
partition->ClearData(
|
||||
@ -1903,11 +1906,13 @@ TEST_F(StoragePartitionImplTest, ConversionsClearDataForFilter) {
|
||||
.SetReportingOrigin(reporter)
|
||||
.SetDestinationOrigin(conv)
|
||||
.SetExpiry(base::Days(2))
|
||||
.Build());
|
||||
.Build(),
|
||||
GlobalRenderFrameHostId());
|
||||
attribution_manager->HandleTrigger(TriggerBuilder()
|
||||
.SetDestinationOrigin(conv)
|
||||
.SetReportingOrigin(reporter)
|
||||
.Build());
|
||||
.Build(),
|
||||
GlobalRenderFrameHostId());
|
||||
}
|
||||
|
||||
EXPECT_EQ(5u, GetAttributionReportsForTesting(attribution_manager).size());
|
||||
|
@ -503,6 +503,7 @@ bool ContentBrowserClient::IsInterestGroupAPIAllowed(
|
||||
bool ContentBrowserClient::IsAttributionReportingOperationAllowed(
|
||||
content::BrowserContext* browser_context,
|
||||
AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* source_origin,
|
||||
const url::Origin* destination_origin,
|
||||
const url::Origin* reporting_origin) {
|
||||
|
@ -875,6 +875,7 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
virtual bool IsAttributionReportingOperationAllowed(
|
||||
content::BrowserContext* browser_context,
|
||||
AttributionReportingOperation operation,
|
||||
content::RenderFrameHost* rfh,
|
||||
const url::Origin* source_origin,
|
||||
const url::Origin* destination_origin,
|
||||
const url::Origin* reporting_origin);
|
||||
|
Reference in New Issue
Block a user