Commit c2782790 authored by John Delaney's avatar John Delaney Committed by Chromium LUCI CQ

[conversions] Integrate API with privacy sandbox settings

What:
Adds new chrome/ layer embedder controls for the Conversion Measurement
API which proxy to privacy sandbox settings.

Why:
The existing integration only checks for 3P cookie blocking, whereas
the privacy sandbox settings check whether 3Ps are allowed for a given
context.

This also fixes a privacy sandbox settings bug in which the wrong
origin was supplied when checking if a report can be sent for a given
set of origins.

Note: This was previously https://ccrev.com/c/2613686, but that change
was accidentally deleted.

Bug: 1163721
Change-Id: I10aba286ad7c641fe8f19f8ad327cf6eabdc3c33
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2627093
Commit-Queue: John Delaney <johnidel@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarCharlie Harrison <csharrison@chromium.org>
Reviewed-by: default avatarTheodore Olsauskas-Warren <sauski@google.com>
Cr-Commit-Position: refs/heads/master@{#843857}
parent 72bac5ab
...@@ -116,6 +116,8 @@ ...@@ -116,6 +116,8 @@
#include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service.h"
#include "chrome/browser/previews/previews_service_factory.h" #include "chrome/browser/previews/previews_service_factory.h"
#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/browser/previews/previews_ui_tab_helper.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/profiles/profile_io_data.h"
...@@ -2785,14 +2787,47 @@ std::string ChromeContentBrowserClient::GetWebBluetoothBlocklist() { ...@@ -2785,14 +2787,47 @@ std::string ChromeContentBrowserClient::GetWebBluetoothBlocklist() {
"blocklist_additions"); "blocklist_additions");
} }
bool ChromeContentBrowserClient::AllowConversionMeasurement( bool ChromeContentBrowserClient::IsConversionMeasurementAllowed(
content::BrowserContext* browser_context) { content::BrowserContext* browser_context) {
// For now, disable conversion measurement if third party cookie blocking is
// enabled.
// TODO(crbug.com/1058018): Add dedicated UI to this feature.
Profile* profile = Profile::FromBrowserContext(browser_context); Profile* profile = Profile::FromBrowserContext(browser_context);
auto cookie_settings = CookieSettingsFactory::GetForProfile(profile); PrivacySandboxSettings* privacy_sandbox_settings =
return !cookie_settings->ShouldBlockThirdPartyCookies(); PrivacySandboxSettingsFactory::GetForProfile(profile);
return privacy_sandbox_settings &&
privacy_sandbox_settings->IsPrivacySandboxAllowed();
}
bool ChromeContentBrowserClient::IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) {
Profile* profile = Profile::FromBrowserContext(browser_context);
PrivacySandboxSettings* privacy_sandbox_settings =
PrivacySandboxSettingsFactory::GetForProfile(profile);
if (!privacy_sandbox_settings)
return false;
switch (operation) {
case ConversionMeasurementOperation::kImpression:
DCHECK(impression_origin);
DCHECK(reporting_origin);
return privacy_sandbox_settings->IsConversionMeasurementAllowed(
*impression_origin, *reporting_origin);
case ConversionMeasurementOperation::kConversion:
DCHECK(conversion_origin);
DCHECK(reporting_origin);
return privacy_sandbox_settings->IsConversionMeasurementAllowed(
*conversion_origin, *reporting_origin);
case ConversionMeasurementOperation::kReport:
DCHECK(impression_origin);
DCHECK(conversion_origin);
DCHECK(reporting_origin);
return privacy_sandbox_settings->ShouldSendConversionReport(
*impression_origin, *conversion_origin, *reporting_origin);
}
} }
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
......
...@@ -291,8 +291,14 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { ...@@ -291,8 +291,14 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
const url::Origin& requesting_origin, const url::Origin& requesting_origin,
const url::Origin& embedding_origin) override; const url::Origin& embedding_origin) override;
std::string GetWebBluetoothBlocklist() override; std::string GetWebBluetoothBlocklist() override;
bool AllowConversionMeasurement( bool IsConversionMeasurementAllowed(
content::BrowserContext* browser_context) override; content::BrowserContext* browser_context) override;
bool IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) override;
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
void OnTrustAnchorUsed(content::BrowserContext* browser_context) override; void OnTrustAnchorUsed(content::BrowserContext* browser_context) override;
#endif #endif
......
...@@ -118,7 +118,7 @@ bool PrivacySandboxSettings::ShouldSendConversionReport( ...@@ -118,7 +118,7 @@ bool PrivacySandboxSettings::ShouldSendConversionReport(
return IsPrivacySandboxAllowedForContext( return IsPrivacySandboxAllowedForContext(
reporting_origin.GetURL(), impression_origin, cookie_settings) && reporting_origin.GetURL(), impression_origin, cookie_settings) &&
IsPrivacySandboxAllowedForContext(reporting_origin.GetURL(), IsPrivacySandboxAllowedForContext(reporting_origin.GetURL(),
reporting_origin, cookie_settings); conversion_origin, cookie_settings);
} }
bool PrivacySandboxSettings::IsPrivacySandboxAllowed() { bool PrivacySandboxSettings::IsPrivacySandboxAllowed() {
......
...@@ -209,10 +209,18 @@ TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) { ...@@ -209,10 +209,18 @@ TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) {
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed( EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com")))); url::Origin::Create(GURL("https://embedded.com"))));
// Should block due to impression origin.
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport( EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")), url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com")))); url::Origin::Create(GURL("https://embedded.com"))));
// Should block due to conversion origin.
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
} }
TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) { TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) {
......
...@@ -160,11 +160,6 @@ void ConversionHost::DidFinishNavigation(NavigationHandle* navigation_handle) { ...@@ -160,11 +160,6 @@ void ConversionHost::DidFinishNavigation(NavigationHandle* navigation_handle) {
return; return;
} }
if (!GetContentClient()->browser()->AllowConversionMeasurement(
web_contents()->GetBrowserContext())) {
return;
}
// Convert |impression| into a StorableImpression that can be forwarded to // Convert |impression| into a StorableImpression that can be forwarded to
// storage. If a reporting origin was not provided, default to the conversion // storage. If a reporting origin was not provided, default to the conversion
// destination for reporting. // destination for reporting.
...@@ -172,6 +167,14 @@ void ConversionHost::DidFinishNavigation(NavigationHandle* navigation_handle) { ...@@ -172,6 +167,14 @@ void ConversionHost::DidFinishNavigation(NavigationHandle* navigation_handle) {
? impression_origin ? impression_origin
: *impression.reporting_origin; : *impression.reporting_origin;
if (!GetContentClient()->browser()->IsConversionMeasurementOperationAllowed(
web_contents()->GetBrowserContext(),
ContentBrowserClient::ConversionMeasurementOperation::kImpression,
&impression_origin, nullptr /* conversion_origin */,
&reporting_origin)) {
return;
}
// Conversion measurement is only allowed in secure contexts. // Conversion measurement is only allowed in secure contexts.
if (!network::IsOriginPotentiallyTrustworthy(impression_origin) || if (!network::IsOriginPotentiallyTrustworthy(impression_origin) ||
!network::IsOriginPotentiallyTrustworthy(reporting_origin) || !network::IsOriginPotentiallyTrustworthy(reporting_origin) ||
...@@ -213,10 +216,11 @@ void ConversionHost::RegisterConversion( ...@@ -213,10 +216,11 @@ void ConversionHost::RegisterConversion(
if (!conversion_manager) if (!conversion_manager)
return; return;
url::Origin conversion_origin = render_frame_host->GetLastCommittedOrigin();
// Only allow conversion registration on secure pages with a secure conversion // Only allow conversion registration on secure pages with a secure conversion
// redirects. // redirects.
if (!network::IsOriginPotentiallyTrustworthy( if (!network::IsOriginPotentiallyTrustworthy(conversion_origin) ||
render_frame_host->GetLastCommittedOrigin()) ||
!network::IsOriginPotentiallyTrustworthy(conversion->reporting_origin)) { !network::IsOriginPotentiallyTrustworthy(conversion->reporting_origin)) {
mojo::ReportBadMessage( mojo::ReportBadMessage(
"blink.mojom.ConversionHost can only be used in secure contexts with a " "blink.mojom.ConversionHost can only be used in secure contexts with a "
...@@ -224,8 +228,11 @@ void ConversionHost::RegisterConversion( ...@@ -224,8 +228,11 @@ void ConversionHost::RegisterConversion(
return; return;
} }
if (!GetContentClient()->browser()->AllowConversionMeasurement( if (!GetContentClient()->browser()->IsConversionMeasurementOperationAllowed(
web_contents()->GetBrowserContext())) { web_contents()->GetBrowserContext(),
ContentBrowserClient::ConversionMeasurementOperation::kConversion,
nullptr /* impression_origin */, &conversion_origin,
&conversion->reporting_origin)) {
return; return;
} }
......
...@@ -50,6 +50,8 @@ class CONTENT_EXPORT ConversionHost : public WebContentsObserver, ...@@ -50,6 +50,8 @@ class CONTENT_EXPORT ConversionHost : public WebContentsObserver,
NoManager_NoPerPageConversionMetrics); NoManager_NoPerPageConversionMetrics);
FRIEND_TEST_ALL_PREFIXES(ConversionHostTest, FRIEND_TEST_ALL_PREFIXES(ConversionHostTest,
ValidConversionWithEmbedderDisable_NoConversion); ValidConversionWithEmbedderDisable_NoConversion);
FRIEND_TEST_ALL_PREFIXES(ConversionHostTest,
EmbedderDisabledContext_ConversionDisallowed);
ConversionHost( ConversionHost(
WebContents* web_contents, WebContents* web_contents,
......
...@@ -168,6 +168,91 @@ TEST_F(ConversionHostTest, ValidConversionWithEmbedderDisable_NoConversion) { ...@@ -168,6 +168,91 @@ TEST_F(ConversionHostTest, ValidConversionWithEmbedderDisable_NoConversion) {
SetBrowserClientForTesting(old_browser_client); SetBrowserClientForTesting(old_browser_client);
} }
TEST_F(ConversionHostTest, EmbedderDisabledContext_ConversionDisallowed) {
ConfigurableConversionTestBrowserClient browser_client;
ContentBrowserClient* old_browser_client =
SetBrowserClientForTesting(&browser_client);
browser_client.BlockConversionMeasurementInContext(
base::nullopt /* impression_origin */,
base::make_optional(url::Origin::Create(GURL("https://top.example"))),
base::make_optional(
url::Origin::Create(GURL("https://embedded.example"))));
struct {
GURL top_frame_url;
GURL reporting_origin;
bool conversion_allowed;
} kTestCases[] = {
{GURL("https://top.example"), GURL("https://embedded.example"), false},
{GURL("https://embedded.example"), GURL("https://top.example"), true},
{GURL("https://other.example"), GURL("https://embedded.example"), true}};
for (const auto& test_case : kTestCases) {
contents()->NavigateAndCommit(test_case.top_frame_url);
conversion_host()->SetCurrentTargetFrameForTesting(main_rfh());
blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New();
conversion->reporting_origin =
url::Origin::Create(test_case.reporting_origin);
conversion_host()->RegisterConversion(std::move(conversion));
EXPECT_EQ(static_cast<size_t>(test_case.conversion_allowed),
test_manager_.num_conversions())
<< "Top frame url: " << test_case.top_frame_url
<< ", reporting origin: " << test_case.reporting_origin;
test_manager_.Reset();
}
SetBrowserClientForTesting(old_browser_client);
}
TEST_F(ConversionHostTest, EmbedderDisabledContext_ImpressionDisallowed) {
ConfigurableConversionTestBrowserClient browser_client;
ContentBrowserClient* old_browser_client =
SetBrowserClientForTesting(&browser_client);
browser_client.BlockConversionMeasurementInContext(
base::make_optional(url::Origin::Create(GURL("https://top.example"))),
base::nullopt /* conversion_origin */,
base::make_optional(
url::Origin::Create(GURL("https://embedded.example"))));
struct {
GURL top_frame_url;
GURL reporting_origin;
bool impression_allowed;
} kTestCases[] = {
{GURL("https://top.example"), GURL("https://embedded.example"), false},
{GURL("https://embedded.example"), GURL("https://top.example"), true},
{GURL("https://other.example"), GURL("https://embedded.example"), true}};
for (const auto& test_case : kTestCases) {
contents()->NavigateAndCommit(test_case.top_frame_url);
auto navigation = NavigationSimulatorImpl::CreateRendererInitiated(
GURL(kConversionUrl), main_rfh());
navigation->SetInitiatorFrame(main_rfh());
blink::Impression impression;
impression.reporting_origin =
url::Origin::Create(GURL(test_case.reporting_origin));
impression.conversion_destination =
url::Origin::Create(GURL(kConversionUrl));
navigation->set_impression(std::move(impression));
navigation->Commit();
EXPECT_EQ(static_cast<size_t>(test_case.impression_allowed),
test_manager_.num_impressions())
<< "Top frame url: " << test_case.top_frame_url
<< ", reporting origin: " << test_case.reporting_origin;
test_manager_.Reset();
}
SetBrowserClientForTesting(old_browser_client);
}
TEST_F(ConversionHostTest, ValidImpressionWithEmbedderDisable_NoImpression) { TEST_F(ConversionHostTest, ValidImpressionWithEmbedderDisable_NoImpression) {
ConversionDisallowingContentBrowserClient disallowed_browser_client; ConversionDisallowingContentBrowserClient disallowed_browser_client;
ContentBrowserClient* old_browser_client = ContentBrowserClient* old_browser_client =
......
...@@ -76,7 +76,7 @@ void ConversionInternalsHandlerImpl::IsMeasurementEnabled( ...@@ -76,7 +76,7 @@ void ConversionInternalsHandlerImpl::IsMeasurementEnabled(
content::WebContents* contents = web_ui_->GetWebContents(); content::WebContents* contents = web_ui_->GetWebContents();
bool measurement_enabled = bool measurement_enabled =
manager_provider_->GetManager(contents) && manager_provider_->GetManager(contents) &&
GetContentClient()->browser()->AllowConversionMeasurement( GetContentClient()->browser()->IsConversionMeasurementAllowed(
contents->GetBrowserContext()); contents->GetBrowserContext());
std::move(callback).Run(measurement_enabled); std::move(callback).Run(measurement_enabled);
} }
......
...@@ -64,13 +64,17 @@ void ConversionReporterImpl::SendNextReport() { ...@@ -64,13 +64,17 @@ void ConversionReporterImpl::SendNextReport() {
// Send the next report and remove it from the queue. Bind the conversion id // Send the next report and remove it from the queue. Bind the conversion id
// to the sent callback so we know which conversion report has finished // to the sent callback so we know which conversion report has finished
// sending. // sending.
if (GetContentClient()->browser()->AllowConversionMeasurement( ConversionReport* report = report_queue_.top().get();
partition_->browser_context())) { if (GetContentClient()->browser()->IsConversionMeasurementOperationAllowed(
partition_->browser_context(),
ContentBrowserClient::ConversionMeasurementOperation::kReport,
&report->impression.impression_origin(),
&report->impression.conversion_origin(),
&report->impression.reporting_origin())) {
network_sender_->SendReport( network_sender_->SendReport(
report_queue_.top().get(), report_queue_.top().get(),
base::BindOnce(&ConversionReporterImpl::OnReportSent, base::BindOnce(&ConversionReporterImpl::OnReportSent,
base::Unretained(this), base::Unretained(this), report->conversion_id.value()));
*report_queue_.top()->conversion_id));
} else { } else {
// If measurement is disallowed, just drop the report on the floor. We need // If measurement is disallowed, just drop the report on the floor. We need
// to make sure we forward that the report was "sent" to ensure it is // to make sure we forward that the report was "sent" to ensure it is
......
...@@ -53,6 +53,11 @@ class MockNetworkSender : public ConversionReporterImpl::NetworkSender { ...@@ -53,6 +53,11 @@ class MockNetworkSender : public ConversionReporterImpl::NetworkSender {
size_t num_reports_sent() { return num_reports_sent_; } size_t num_reports_sent() { return num_reports_sent_; }
void Reset() {
num_reports_sent_ = 0u;
last_sent_report_id_ = -1;
}
private: private:
size_t num_reports_sent_ = 0u; size_t num_reports_sent_ = 0u;
int64_t last_sent_report_id_ = -1; int64_t last_sent_report_id_ = -1;
...@@ -223,4 +228,64 @@ TEST_F(ConversionReporterImplTest, EmbedderDisallowsConversions_ReportNotSent) { ...@@ -223,4 +228,64 @@ TEST_F(ConversionReporterImplTest, EmbedderDisallowsConversions_ReportNotSent) {
SetBrowserClientForTesting(old_browser_client); SetBrowserClientForTesting(old_browser_client);
} }
TEST_F(ConversionReporterImplTest, EmbedderDisallowedContext_ReportNotSent) {
ConfigurableConversionTestBrowserClient browser_client;
ContentBrowserClient* old_browser_client =
SetBrowserClientForTesting(&browser_client);
browser_client.BlockConversionMeasurementInContext(
base::make_optional(
url::Origin::Create(GURL("https://impression.example"))),
base::make_optional(
url::Origin::Create(GURL("https://conversion.example"))),
base::make_optional(
url::Origin::Create(GURL("https://reporting.example"))));
struct {
GURL impression_origin;
GURL conversion_origin;
GURL reporting_origin;
bool report_allowed;
} kTestCases[] = {
{GURL("https://impression.example"), GURL("https://conversion.example"),
GURL("https://reporting.example"), false},
{GURL("https://conversion.example"), GURL("https://impression.example"),
GURL("https://reporting.example"), true},
{GURL("https://impression.example"), GURL("https://conversion.example"),
GURL("https://other.example"), true},
};
for (const auto& test_case : kTestCases) {
auto impression =
ImpressionBuilder(base::Time())
.SetImpressionOrigin(
url::Origin::Create(test_case.impression_origin))
.SetConversionOrigin(
url::Origin::Create(test_case.conversion_origin))
.SetReportingOrigin(url::Origin::Create(test_case.reporting_origin))
.Build();
std::vector<ConversionReport> reports{
ConversionReport(std::move(impression),
/*conversion_data=*/"", clock().Now(), clock().Now(),
/*conversion_id=*/1)};
reporter_->AddReportsToQueue(std::move(reports),
base::BindRepeating([](int64_t conversion_id) {
EXPECT_EQ(1L, conversion_id);
}));
// Fast forward by 0, as we yield the thread when a report is scheduled to
// be sent.
task_environment_.FastForwardBy(base::TimeDelta());
EXPECT_EQ(static_cast<size_t>(test_case.report_allowed),
sender_->num_reports_sent())
<< "impression_origin; " << test_case.impression_origin
<< ", conversion_origin: " << test_case.conversion_origin
<< ", reporting_origin: " << test_case.reporting_origin;
sender_->Reset();
}
SetBrowserClientForTesting(old_browser_client);
}
} // namespace content } // namespace content
...@@ -31,11 +31,61 @@ const int64_t kExpiryTime = 30; ...@@ -31,11 +31,61 @@ const int64_t kExpiryTime = 30;
} // namespace } // namespace
bool ConversionDisallowingContentBrowserClient::AllowConversionMeasurement( bool ConversionDisallowingContentBrowserClient::IsConversionMeasurementAllowed(
BrowserContext* context) { content::BrowserContext* browser_context) {
return false; return false;
} }
bool ConversionDisallowingContentBrowserClient::
IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) {
return false;
}
ConfigurableConversionTestBrowserClient::
ConfigurableConversionTestBrowserClient() = default;
ConfigurableConversionTestBrowserClient::
~ConfigurableConversionTestBrowserClient() = default;
bool ConfigurableConversionTestBrowserClient::
IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) {
if (!!blocked_impression_origin_ != !!impression_origin ||
!!blocked_conversion_origin_ != !!conversion_origin ||
!!blocked_reporting_origin_ != !!reporting_origin) {
return true;
}
// Allow the operation if any rule doesn't match.
if ((impression_origin &&
*blocked_impression_origin_ != *impression_origin) ||
(conversion_origin &&
*blocked_conversion_origin_ != *conversion_origin) ||
(reporting_origin && *blocked_reporting_origin_ != *reporting_origin)) {
return true;
}
return false;
}
void ConfigurableConversionTestBrowserClient::
BlockConversionMeasurementInContext(
base::Optional<url::Origin> impression_origin,
base::Optional<url::Origin> conversion_origin,
base::Optional<url::Origin> reporting_origin) {
blocked_impression_origin_ = impression_origin;
blocked_conversion_origin_ = conversion_origin;
blocked_reporting_origin_ = reporting_origin;
}
ConfigurableStorageDelegate::ConfigurableStorageDelegate() = default; ConfigurableStorageDelegate::ConfigurableStorageDelegate() = default;
ConfigurableStorageDelegate::~ConfigurableStorageDelegate() = default; ConfigurableStorageDelegate::~ConfigurableStorageDelegate() = default;
......
...@@ -32,7 +32,44 @@ class ConversionDisallowingContentBrowserClient ...@@ -32,7 +32,44 @@ class ConversionDisallowingContentBrowserClient
~ConversionDisallowingContentBrowserClient() override = default; ~ConversionDisallowingContentBrowserClient() override = default;
// ContentBrowserClient: // ContentBrowserClient:
bool AllowConversionMeasurement(BrowserContext* context) override; bool IsConversionMeasurementAllowed(
content::BrowserContext* browser_context) override;
bool IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) override;
};
// Configurable browser client capable of blocking conversion operations in a
// single embedded context.
class ConfigurableConversionTestBrowserClient
: public TestContentBrowserClient {
public:
ConfigurableConversionTestBrowserClient();
~ConfigurableConversionTestBrowserClient() override;
// ContentBrowserClient:
bool IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) override;
// Sets the origins where conversion measurement is blocked. This only blocks
// an operation if all origins match in
// `AllowConversionMeasurementOperation()`.
void BlockConversionMeasurementInContext(
base::Optional<url::Origin> impression_origin,
base::Optional<url::Origin> conversion_origin,
base::Optional<url::Origin> reporting_origin);
private:
base::Optional<url::Origin> blocked_impression_origin_;
base::Optional<url::Origin> blocked_conversion_origin_;
base::Optional<url::Origin> blocked_reporting_origin_;
}; };
class ConfigurableStorageDelegate : public ConversionStorage::Delegate { class ConfigurableStorageDelegate : public ConversionStorage::Delegate {
......
...@@ -427,11 +427,20 @@ std::string ContentBrowserClient::GetWebBluetoothBlocklist() { ...@@ -427,11 +427,20 @@ std::string ContentBrowserClient::GetWebBluetoothBlocklist() {
return std::string(); return std::string();
} }
bool ContentBrowserClient::AllowConversionMeasurement( bool ContentBrowserClient::IsConversionMeasurementAllowed(
content::BrowserContext* browser_context) { content::BrowserContext* browser_context) {
return true; return true;
} }
bool ContentBrowserClient::IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin) {
return true;
}
scoped_refptr<QuotaPermissionContext> scoped_refptr<QuotaPermissionContext>
ContentBrowserClient::CreateQuotaPermissionContext() { ContentBrowserClient::CreateQuotaPermissionContext() {
return nullptr; return nullptr;
......
...@@ -747,14 +747,37 @@ class CONTENT_EXPORT ContentBrowserClient { ...@@ -747,14 +747,37 @@ class CONTENT_EXPORT ContentBrowserClient {
// "1812:e, 00001800-0000-1000-8000-00805f9b34fb:w, ignored:1, alsoignored." // "1812:e, 00001800-0000-1000-8000-00805f9b34fb:w, ignored:1, alsoignored."
virtual std::string GetWebBluetoothBlocklist(); virtual std::string GetWebBluetoothBlocklist();
// Allows the embedder to control the conversion measurement API. // Returns whether conversion measurement is allowed anywhere in
// This gates the following behaviors: // |browser_context|. Returns false if Conversion Measurement is not allowed
// - Impression registration // by default on any origin.
// - Conversion registration virtual bool IsConversionMeasurementAllowed(
// - Conversion reports
virtual bool AllowConversionMeasurement(
content::BrowserContext* browser_context); content::BrowserContext* browser_context);
enum class ConversionMeasurementOperation {
kImpression,
kConversion,
kReport,
};
// Allows the embedder to control if conversion measurement API operations can
// happen in a given context. Origins must be provided for a given operation
// as follows:
// - kImpression must provide a non-null `impression_origin` and
// `reporting_origin`
// - kConversion must provide a non-null `conversion_origin` and
// `reporting_origin`
// - kReport must provide all non-null origins
//
// When gating an operation, this should not be checked in conjunction with
// `IsConversionMeasurementAllowed()`, as the API may not be allowed by
// default, but allowed in a specific context due to an exception rule.
virtual bool IsConversionMeasurementOperationAllowed(
content::BrowserContext* browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin);
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
// Notification that a trust anchor was used by the given user. // Notification that a trust anchor was used by the given user.
virtual void OnTrustAnchorUsed(BrowserContext* browser_context) {} virtual void OnTrustAnchorUsed(BrowserContext* browser_context) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment