Skip to content

Commit

Permalink
Propagate Attribution Reporting OS registrations from blink to browser
Browse files Browse the repository at this point in the history
It is an error to attempt to register both web and OS sources or
triggers in the same response, regardless of whether the platform
supports OS registrations at all, but we skip parsing the *contents*
of OS-registration headers when OS support is disabled, for efficiency.

Note that we cannot add web tests for the InvalidRegisterOsSourceHeader
and InvalidRegisterOsTriggerHeader DevTools issue types as there is no
way to override the OS support value there.

Bug: 1378298
Change-Id: I6928b18c4ef8131d5eabba40d9bfb2c51c61a1af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3987771
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
Reviewed-by: Nate Chapin <japhet@chromium.org>
Quick-Run: Andrew Paseltiner <apaseltiner@chromium.org>
Reviewed-by: Nan Lin <linnan@chromium.org>
Commit-Queue: Andrew Paseltiner <apaseltiner@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1116351}
  • Loading branch information
Andrew Paseltiner authored and Chromium LUCI CQ committed Mar 13, 2023
1 parent 45f99bb commit 9c0db26
Show file tree
Hide file tree
Showing 21 changed files with 604 additions and 139 deletions.
Expand Up @@ -1421,6 +1421,92 @@ IN_PROC_BROWSER_TEST_F(
"web, os");
}

struct OsRegistrationTestCase {
const char* name;
const char* header;
std::vector<GURL> expected_os_sources;
std::vector<GURL> expected_os_triggers;
};

class AttributionSrcCrossAppWebEnabledOsRegistrationBrowserTest
: public AttributionSrcCrossAppWebEnabledBrowserTest,
public ::testing::WithParamInterface<OsRegistrationTestCase> {};

INSTANTIATE_TEST_SUITE_P(
All,
AttributionSrcCrossAppWebEnabledOsRegistrationBrowserTest,
::testing::Values(
OsRegistrationTestCase{
.name = "source",
.header = "Attribution-Reporting-Register-OS-Source",
.expected_os_sources = {GURL("https://r.test/x")},
},
OsRegistrationTestCase{
.name = "trigger",
.header = "Attribution-Reporting-Register-OS-Trigger",
.expected_os_triggers = {GURL("https://r.test/x")},
}),
[](const auto& info) { return info.param.name; }); // test name generator

IN_PROC_BROWSER_TEST_P(
AttributionSrcCrossAppWebEnabledOsRegistrationBrowserTest,
Register) {
const auto& test_case = GetParam();

// Create a separate server as we cannot register a `ControllableHttpResponse`
// after the server starts.
auto https_server = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
net::test_server::RegisterDefaultHandlers(https_server.get());
https_server->ServeFilesFromSourceDirectory(
"content/test/data/attribution_reporting");
https_server->ServeFilesFromSourceDirectory("content/test/data");

std::unique_ptr<MockDataHost> data_host;
base::RunLoop loop;
EXPECT_CALL(mock_attribution_host(), RegisterDataHost)
.WillOnce(
[&](mojo::PendingReceiver<blink::mojom::AttributionDataHost> host,
RegistrationType) {
data_host = GetRegisteredDataHost(std::move(host));
loop.Quit();
});

auto register_response =
std::make_unique<net::test_server::ControllableHttpResponse>(
https_server.get(), "/register");
ASSERT_TRUE(https_server->Start());

AttributionOsLevelManagerAndroid::ScopedOsSupportForTesting
scoped_os_support_setting(
attribution_reporting::mojom::OsSupport::kEnabled);

GURL page_url =
https_server->GetURL("b.test", "/page_with_impression_creator.html");
ASSERT_TRUE(NavigateToURL(web_contents(), page_url));

GURL register_url = https_server->GetURL("d.test", "/register");
ASSERT_TRUE(ExecJs(web_contents(),
JsReplace("createAttributionSrcImg($1);", register_url)));

register_response->WaitForRequest();

auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
http_response->AddCustomHeader(test_case.header, R"("https://r.test/x")");
register_response->Send(http_response->ToResponseString());
register_response->Done();

if (!data_host) {
loop.Run();
}
data_host->WaitForOsSources(test_case.expected_os_sources.size());
data_host->WaitForOsTriggers(test_case.expected_os_triggers.size());

EXPECT_EQ(data_host->os_sources(), test_case.expected_os_sources);
EXPECT_EQ(data_host->os_triggers(), test_case.expected_os_triggers);
}

#endif // BUILDFLAG(IS_ANDROID)

} // namespace content
38 changes: 35 additions & 3 deletions content/browser/attribution_reporting/test/mock_data_host.cc
Expand Up @@ -21,6 +21,7 @@
#include "services/network/public/cpp/trigger_attestation.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom.h"
#include "url/gurl.h"

namespace content {

Expand Down Expand Up @@ -69,9 +70,40 @@ void MockDataHost::TriggerDataAvailable(
}

#if BUILDFLAG(IS_ANDROID)
void MockDataHost::OsSourceDataAvailable(const GURL& registration_url) {}
void MockDataHost::OsTriggerDataAvailable(const GURL& registration_url) {}
#endif

void MockDataHost::OsSourceDataAvailable(const GURL& registration_url) {
os_sources_.push_back(registration_url);
if (os_sources_.size() < min_os_sources_count_) {
return;
}
wait_loop_.Quit();
}

void MockDataHost::OsTriggerDataAvailable(const GURL& registration_url) {
os_triggers_.push_back(registration_url);
if (os_triggers_.size() < min_os_triggers_count_) {
return;
}
wait_loop_.Quit();
}

void MockDataHost::WaitForOsSources(size_t num_os_sources) {
min_os_sources_count_ = num_os_sources;
if (os_sources_.size() >= min_os_sources_count_) {
return;
}
wait_loop_.Run();
}

void MockDataHost::WaitForOsTriggers(size_t num_os_triggers) {
min_os_triggers_count_ = num_os_triggers;
if (os_triggers_.size() >= min_os_triggers_count_) {
return;
}
wait_loop_.Run();
}

#endif // BUILDFLAG(IS_ANDROID)

std::unique_ptr<MockDataHost> GetRegisteredDataHost(
mojo::PendingReceiver<blink::mojom::AttributionDataHost> data_host) {
Expand Down
23 changes: 17 additions & 6 deletions content/browser/attribution_reporting/test/mock_data_host.h
Expand Up @@ -17,9 +17,9 @@
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom.h"

namespace attribution_reporting {
class SuitableOrigin;
class GURL;

namespace attribution_reporting {
struct SourceRegistration;
struct TriggerRegistration;
} // namespace attribution_reporting
Expand All @@ -31,10 +31,6 @@ class PendingReceiver;

} // namespace mojo

namespace network {
class TriggerAttestation;
} // namespace network

namespace content {

class MockDataHost : public blink::mojom::AttributionDataHost {
Expand All @@ -56,6 +52,13 @@ class MockDataHost : public blink::mojom::AttributionDataHost {
return trigger_data_;
}

#if BUILDFLAG(IS_ANDROID)
const std::vector<GURL>& os_sources() const { return os_sources_; }
const std::vector<GURL>& os_triggers() const { return os_triggers_; }
void WaitForOsSources(size_t);
void WaitForOsTriggers(size_t);
#endif

mojo::Receiver<blink::mojom::AttributionDataHost>& receiver() {
return receiver_;
}
Expand All @@ -80,6 +83,14 @@ class MockDataHost : public blink::mojom::AttributionDataHost {
size_t min_trigger_data_count_ = 0;
std::vector<attribution_reporting::TriggerRegistration> trigger_data_;

#if BUILDFLAG(IS_ANDROID)
size_t min_os_sources_count_ = 0;
std::vector<GURL> os_sources_;

size_t min_os_triggers_count_ = 0;
std::vector<GURL> os_triggers_;
#endif

base::RunLoop wait_loop_;
mojo::Receiver<blink::mojom::AttributionDataHost> receiver_{this};
};
Expand Down
Expand Up @@ -712,6 +712,11 @@ experimental domain Audits
SourceAndTriggerHeaders
SourceIgnored
TriggerIgnored
OsSourceIgnored
OsTriggerIgnored
InvalidRegisterOsSourceHeader
InvalidRegisterOsTriggerHeader
WebAndOsHeaders

# Details for issues around "Attribution Reporting API" usage.
# Explainer: https://github.com/WICG/attribution-reporting-api
Expand Down

0 comments on commit 9c0db26

Please sign in to comment.