Commit b535aa4a authored by Eric Robinson's avatar Eric Robinson Committed by Commit Bot

Adding reporting for third party content that accesses storage.

This CL adds UseCounters for activation of third party frames,
as well as for general access to these frames, and third parties
that had frames that were both activated and accessed.

Change-Id: Ib366336a2553c5625341147e82875c4265b42225
Bug: 1115657
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402196
Commit-Queue: Eric Robinson <ericrobinson@chromium.org>
Reviewed-by: default avatarCharlie Harrison <csharrison@chromium.org>
Reviewed-by: default avatarYao Xiao <yaoxia@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813760}
parent 309b54c3
...@@ -37,35 +37,11 @@ bool IsSameSite(const GURL& url1, const GURL& url2) { ...@@ -37,35 +37,11 @@ bool IsSameSite(const GURL& url1, const GURL& url2) {
} // namespace } // namespace
ThirdPartyMetricsObserver::AccessedTypes::AccessedTypes(
AccessType access_type) {
switch (access_type) {
case AccessType::kCookieRead:
cookie_read = true;
break;
case AccessType::kCookieWrite:
cookie_write = true;
break;
case AccessType::kLocalStorage:
local_storage = true;
break;
case AccessType::kSessionStorage:
session_storage = true;
break;
// No extra metadata required for the following types as they only record
// use counters.
case AccessType::kFileSystem:
case AccessType::kIndexedDb:
case AccessType::kCacheStorage:
break;
case AccessType::kUnknown:
NOTREACHED();
break;
}
}
ThirdPartyMetricsObserver::ThirdPartyMetricsObserver() = default; ThirdPartyMetricsObserver::ThirdPartyMetricsObserver() = default;
ThirdPartyMetricsObserver::~ThirdPartyMetricsObserver() = default; ThirdPartyMetricsObserver::~ThirdPartyMetricsObserver() = default;
ThirdPartyMetricsObserver::ThirdPartyInfo::ThirdPartyInfo() = default;
ThirdPartyMetricsObserver::ThirdPartyInfo::ThirdPartyInfo(
const ThirdPartyInfo&) = default;
page_load_metrics::PageLoadMetricsObserver::ObservePolicy page_load_metrics::PageLoadMetricsObserver::ObservePolicy
ThirdPartyMetricsObserver::FlushMetricsOnAppEnterBackground( ThirdPartyMetricsObserver::FlushMetricsOnAppEnterBackground(
...@@ -76,6 +52,23 @@ ThirdPartyMetricsObserver::FlushMetricsOnAppEnterBackground( ...@@ -76,6 +52,23 @@ ThirdPartyMetricsObserver::FlushMetricsOnAppEnterBackground(
return STOP_OBSERVING; return STOP_OBSERVING;
} }
void ThirdPartyMetricsObserver::FrameReceivedFirstUserActivation(
content::RenderFrameHost* render_frame_host) {
bool is_third_party = false;
auto* third_party_info = GetThirdPartyInfo(
render_frame_host->GetLastCommittedURL(),
content::WebContents::FromRenderFrameHost(render_frame_host)
->GetMainFrame()
->GetLastCommittedURL(),
is_third_party);
// Update the activation status and record use counters as necessary.
if (is_third_party && third_party_info != nullptr) {
third_party_info->activation = true;
RecordUseCounters(AccessType::kMaxValue, third_party_info);
}
}
void ThirdPartyMetricsObserver::OnComplete( void ThirdPartyMetricsObserver::OnComplete(
const page_load_metrics::mojom::PageLoadTiming& timing) { const page_load_metrics::mojom::PageLoadTiming& timing) {
RecordMetrics(timing); RecordMetrics(timing);
...@@ -113,10 +106,35 @@ void ThirdPartyMetricsObserver::OnCookieChange( ...@@ -113,10 +106,35 @@ void ThirdPartyMetricsObserver::OnCookieChange(
AccessType::kCookieWrite); AccessType::kCookieWrite);
} }
void ThirdPartyMetricsObserver::RecordStorageAccessUseCounter( // TODO(crbug.com/1115657): It would be simpler to just pass in ThirdPartyInfo
AccessType access_type) { // and set the bits appropriately, but because this is called every time an
// access is made, that would mean re-calling old accesses. This could be fixed
// by calling this only when the page is removed or when backgrounded.
void ThirdPartyMetricsObserver::RecordUseCounters(
AccessType access_type,
const ThirdPartyInfo* third_party_info) {
page_load_metrics::mojom::PageLoadFeatures third_party_storage_features; page_load_metrics::mojom::PageLoadFeatures third_party_storage_features;
// We only record access/activation if the third_party_info didn't overflow.
if (third_party_info != nullptr) {
// Record any sort of access.
if (third_party_info->access_types.any()) {
third_party_storage_features.features.push_back(
blink::mojom::WebFeature::kThirdPartyAccess);
}
// Record any sort of activation.
if (third_party_info->activation) {
third_party_storage_features.features.push_back(
blink::mojom::WebFeature::kThirdPartyActivation);
}
// Record the combination of the above two
if (third_party_info->access_types.any() && third_party_info->activation) {
third_party_storage_features.features.push_back(
blink::mojom::WebFeature::kThirdPartyAccessAndActivation);
}
}
// Record the specific type of access, if appropriate.
switch (access_type) { switch (access_type) {
case AccessType::kCookieRead: case AccessType::kCookieRead:
third_party_storage_features.features.push_back( third_party_storage_features.features.push_back(
...@@ -146,14 +164,18 @@ void ThirdPartyMetricsObserver::RecordStorageAccessUseCounter( ...@@ -146,14 +164,18 @@ void ThirdPartyMetricsObserver::RecordStorageAccessUseCounter(
third_party_storage_features.features.push_back( third_party_storage_features.features.push_back(
blink::mojom::WebFeature::kThirdPartyCacheStorage); blink::mojom::WebFeature::kThirdPartyCacheStorage);
break; break;
default default:
: // No feature usage recorded for storage types without a use counter. // No feature usage recorded for storage types without a use counter.
return; // Also nothing reported for non storage access.
break;
} }
page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( // Report the feature usage if there's anything to report.
GetDelegate().GetWebContents()->GetMainFrame(), if (third_party_storage_features.features.size() > 0) {
third_party_storage_features); page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage(
GetDelegate().GetWebContents()->GetMainFrame(),
third_party_storage_features);
}
} }
void ThirdPartyMetricsObserver::OnStorageAccessed( void ThirdPartyMetricsObserver::OnStorageAccessed(
...@@ -220,26 +242,19 @@ void ThirdPartyMetricsObserver::OnTimingUpdate( ...@@ -220,26 +242,19 @@ void ThirdPartyMetricsObserver::OnTimingUpdate(
} }
} }
void ThirdPartyMetricsObserver::OnCookieOrStorageAccess( ThirdPartyMetricsObserver::ThirdPartyInfo*
const GURL& url, ThirdPartyMetricsObserver::GetThirdPartyInfo(const GURL& url,
const GURL& first_party_url, const GURL& first_party_url,
bool blocked_by_policy, bool& is_third_party) {
AccessType access_type) { is_third_party = false;
if (blocked_by_policy) {
should_record_metrics_ = false;
return;
}
if (!url.is_valid())
return;
// TODO(csharrison): Optimize the domain lookup. // TODO(csharrison): Optimize the domain lookup.
// Note: If either |url| or |first_party_url| is empty, SameDomainOrHost will // Note: If either |url| or |first_party_url| is empty, SameDomainOrHost will
// return false, and function execution will continue because it is considered // return false, and function execution will continue because it is considered
// 3rd party. Since |first_party_url| is actually the |site_for_cookies|, this // 3rd party. Since |first_party_url| is actually the |site_for_cookies|, this
// will happen e.g. for a 3rd party iframe on document.cookie access. // will happen e.g. for a 3rd party iframe on document.cookie access.
if (IsSameSite(url, first_party_url)) if (!url.is_valid() || IsSameSite(url, first_party_url))
return; return nullptr;
std::string registrable_domain = std::string registrable_domain =
net::registry_controlled_domains::GetDomainAndRegistry( net::registry_controlled_domains::GetDomainAndRegistry(
...@@ -253,49 +268,48 @@ void ThirdPartyMetricsObserver::OnCookieOrStorageAccess( ...@@ -253,49 +268,48 @@ void ThirdPartyMetricsObserver::OnCookieOrStorageAccess(
if (url.has_host()) { if (url.has_host()) {
registrable_domain = url.host(); registrable_domain = url.host();
} else { } else {
return; return nullptr;
} }
} }
RecordStorageAccessUseCounter(access_type); // If we haven't returned by this point, this is a third party access.
is_third_party = true;
GURL representative_url( GURL representative_url(
base::StrCat({url.scheme(), "://", registrable_domain, "/"})); base::StrCat({url.scheme(), "://", registrable_domain, "/"}));
auto it = all_third_party_info_.find(representative_url);
if (it == all_third_party_info_.end() &&
all_third_party_info_.size() < 1000) { // Bound growth.
it = all_third_party_info_.emplace(url, ThirdPartyInfo()).first;
}
// If there's no valid iterator, we've gone over the size limit for the map.
// TODO(crbug.com/1115657): We probably want UMA to let us know how often we
// might be underreporting.
return (it == all_third_party_info_.end() ? nullptr : &it->second);
}
auto it = third_party_accessed_types_.find(representative_url); void ThirdPartyMetricsObserver::OnCookieOrStorageAccess(
const GURL& url,
if (it != third_party_accessed_types_.end()) { const GURL& first_party_url,
switch (access_type) { bool blocked_by_policy,
case AccessType::kCookieRead: AccessType access_type) {
it->second.cookie_read = true; DCHECK(access_type != AccessType::kUnknown);
break; if (blocked_by_policy) {
case AccessType::kCookieWrite: should_record_metrics_ = false;
it->second.cookie_write = true;
break;
case AccessType::kLocalStorage:
it->second.local_storage = true;
break;
case AccessType::kSessionStorage:
it->second.session_storage = true;
break;
// No metadata is tracked for the following types as they only record use
// counters.
case AccessType::kFileSystem:
case AccessType::kIndexedDb:
case AccessType::kCacheStorage:
break;
case AccessType::kUnknown:
NOTREACHED();
break;
}
return; return;
} }
// Don't let the map grow unbounded. bool is_third_party = false;
if (third_party_accessed_types_.size() >= 1000) auto* third_party_info =
GetThirdPartyInfo(url, first_party_url, is_third_party);
if (!is_third_party)
return; return;
if (third_party_info != nullptr) {
third_party_info->access_types[static_cast<size_t>(access_type)] = true;
}
third_party_accessed_types_.emplace(representative_url, access_type); // Record the use counters as necessary.
RecordUseCounters(access_type, third_party_info);
} }
void ThirdPartyMetricsObserver::RecordMetrics( void ThirdPartyMetricsObserver::RecordMetrics(
...@@ -308,11 +322,16 @@ void ThirdPartyMetricsObserver::RecordMetrics( ...@@ -308,11 +322,16 @@ void ThirdPartyMetricsObserver::RecordMetrics(
int local_storage_origin_access = 0; int local_storage_origin_access = 0;
int session_storage_origin_access = 0; int session_storage_origin_access = 0;
for (auto it : third_party_accessed_types_) { for (auto it : all_third_party_info_) {
cookie_origin_reads += it.second.cookie_read; const ThirdPartyInfo& tpi = it.second;
cookie_origin_writes += it.second.cookie_write; if (tpi.access_types[static_cast<size_t>(AccessType::kCookieRead)])
local_storage_origin_access += it.second.local_storage; ++cookie_origin_reads;
session_storage_origin_access += it.second.session_storage; if (tpi.access_types[static_cast<size_t>(AccessType::kCookieWrite)])
++cookie_origin_writes;
if (tpi.access_types[static_cast<size_t>(AccessType::kLocalStorage)])
++local_storage_origin_access;
if (tpi.access_types[static_cast<size_t>(AccessType::kSessionStorage)])
++session_storage_origin_access;
} }
UMA_HISTOGRAM_COUNTS_1000("PageLoad.Clients.ThirdParty.Origins.CookieRead2", UMA_HISTOGRAM_COUNTS_1000("PageLoad.Clients.ThirdParty.Origins.CookieRead2",
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
class ThirdPartyMetricsObserver class ThirdPartyMetricsObserver
: public page_load_metrics::PageLoadMetricsObserver { : public page_load_metrics::PageLoadMetricsObserver {
public: public:
// TODO(crbug.com/1115657): kUnknown is mostly unused except for passing it as
// a "dummy" type to RecordUseCounters. After we factor out AccessType from
// that method (see other TODOs), we should be able to remove it.
enum class AccessType { enum class AccessType {
kCookieRead, kCookieRead,
kCookieWrite, kCookieWrite,
...@@ -26,6 +29,7 @@ class ThirdPartyMetricsObserver ...@@ -26,6 +29,7 @@ class ThirdPartyMetricsObserver
kIndexedDb, kIndexedDb,
kCacheStorage, kCacheStorage,
kUnknown, kUnknown,
kMaxValue = kUnknown
}; };
ThirdPartyMetricsObserver(); ThirdPartyMetricsObserver();
...@@ -34,6 +38,8 @@ class ThirdPartyMetricsObserver ...@@ -34,6 +38,8 @@ class ThirdPartyMetricsObserver
// page_load_metrics::PageLoadMetricsObserver: // page_load_metrics::PageLoadMetricsObserver:
ObservePolicy FlushMetricsOnAppEnterBackground( ObservePolicy FlushMetricsOnAppEnterBackground(
const page_load_metrics::mojom::PageLoadTiming& timing) override; const page_load_metrics::mojom::PageLoadTiming& timing) override;
void FrameReceivedFirstUserActivation(
content::RenderFrameHost* render_frame_host) override;
void OnComplete( void OnComplete(
const page_load_metrics::mojom::PageLoadTiming& timing) override; const page_load_metrics::mojom::PageLoadTiming& timing) override;
void OnLoadedResource(const page_load_metrics::ExtraRequestCompleteInfo& void OnLoadedResource(const page_load_metrics::ExtraRequestCompleteInfo&
...@@ -58,14 +64,22 @@ class ThirdPartyMetricsObserver ...@@ -58,14 +64,22 @@ class ThirdPartyMetricsObserver
const page_load_metrics::mojom::PageLoadTiming& timing) override; const page_load_metrics::mojom::PageLoadTiming& timing) override;
private: private:
struct AccessedTypes { // The info about the types of activities for a third party.
explicit AccessedTypes(AccessType access_type); struct ThirdPartyInfo {
bool cookie_read = false; ThirdPartyInfo();
bool cookie_write = false; ThirdPartyInfo(const ThirdPartyInfo&);
bool local_storage = false; std::bitset<static_cast<size_t>(AccessType::kMaxValue)> access_types;
bool session_storage = false; bool activation = false;
}; };
// Returns a pointer to the ThirdPartyInfo in all_third_party_info_ for |url|
// and |first_party_url|, adding an entry as necessary. The out parameter
// |is_third_party| indicates whether the two inputs are third party one
// another and may be true with a nullptr return if the map is full.
ThirdPartyInfo* GetThirdPartyInfo(const GURL& url,
const GURL& first_party_url,
bool& is_third_party);
void OnCookieOrStorageAccess(const GURL& url, void OnCookieOrStorageAccess(const GURL& url,
const GURL& first_party_url, const GURL& first_party_url,
bool blocked_by_policy, bool blocked_by_policy,
...@@ -73,14 +87,15 @@ class ThirdPartyMetricsObserver ...@@ -73,14 +87,15 @@ class ThirdPartyMetricsObserver
void RecordMetrics( void RecordMetrics(
const page_load_metrics::mojom::PageLoadTiming& main_frame_timing); const page_load_metrics::mojom::PageLoadTiming& main_frame_timing);
// Records feature usage for |access_type| with use counters. // Records feature usage for teh |access_type|, and also, when present, for
void RecordStorageAccessUseCounter(AccessType access_type); // generic access and activation for the |third_party_info|.
void RecordUseCounters(AccessType access_type,
const ThirdPartyInfo* third_party_info);
AccessType StorageTypeToAccessType( AccessType StorageTypeToAccessType(
page_load_metrics::StorageType storage_type); page_load_metrics::StorageType storage_type);
// A map of third parties that have read or written cookies, or have // A map of third parties and the types of activities they have performed.
// accessed local storage or session storage on this page.
// //
// A third party document.cookie / window.localStorage / // A third party document.cookie / window.localStorage /
// window.sessionStorage happens when the context's scheme://eTLD+1 // window.sessionStorage happens when the context's scheme://eTLD+1
...@@ -88,7 +103,7 @@ class ThirdPartyMetricsObserver ...@@ -88,7 +103,7 @@ class ThirdPartyMetricsObserver
// when the URL request's scheme://eTLD+1 differs from the main frame's. // when the URL request's scheme://eTLD+1 differs from the main frame's.
// For URLs which have no registrable domain, the hostname is used // For URLs which have no registrable domain, the hostname is used
// instead. // instead.
std::map<GURL, AccessedTypes> third_party_accessed_types_; std::map<GURL, ThirdPartyInfo> all_third_party_info_;
// A set of RenderFrameHosts that we've recorded timing data for. The // A set of RenderFrameHosts that we've recorded timing data for. The
// RenderFrameHosts are later removed when they navigate again or are deleted. // RenderFrameHosts are later removed when they navigate again or are deleted.
......
...@@ -111,6 +111,9 @@ class ThirdPartyMetricsObserverBrowserTest : public InProcessBrowserTest { ...@@ -111,6 +111,9 @@ class ThirdPartyMetricsObserverBrowserTest : public InProcessBrowserTest {
waiter->Wait(); waiter->Wait();
} }
// TODO(ericrobinson) The following functions all have an assumed frame.
// Prefer passing in a frame to make the tests clearer and extendable.
void NavigateFrameAndWaitForFCP( void NavigateFrameAndWaitForFCP(
const std::string& host, const std::string& host,
const std::string& path, const std::string& path,
...@@ -137,6 +140,14 @@ class ThirdPartyMetricsObserverBrowserTest : public InProcessBrowserTest { ...@@ -137,6 +140,14 @@ class ThirdPartyMetricsObserverBrowserTest : public InProcessBrowserTest {
EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", url)); EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", url));
} }
void TriggerFrameActivation() {
// Activate one frame by executing a dummy script.
content::RenderFrameHost* ad_frame =
ChildFrameAt(web_contents()->GetMainFrame(), 0);
const std::string no_op_script = "// No-op script";
EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));
}
content::WebContents* web_contents() { content::WebContents* web_contents() {
return browser()->tab_strip_model()->GetActiveWebContents(); return browser()->tab_strip_model()->GetActiveWebContents();
} }
...@@ -227,6 +238,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, NoStorageEvent) { ...@@ -227,6 +238,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, NoStorageEvent) {
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 0); blink::mojom::WebFeature::kThirdPartyCookieWrite, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -244,6 +258,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -244,6 +258,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 0); blink::mojom::WebFeature::kThirdPartyCookieWrite, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -264,6 +281,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -264,6 +281,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1); blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -289,6 +309,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -289,6 +309,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1); blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -313,6 +336,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -313,6 +336,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1); blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -338,6 +364,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -338,6 +364,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 0); blink::mojom::WebFeature::kThirdPartyCookieWrite, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -364,6 +393,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -364,6 +393,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1); blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -387,6 +419,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -387,6 +419,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 0); blink::mojom::WebFeature::kThirdPartyCookieWrite, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
...@@ -410,6 +445,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -410,6 +445,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", "Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1); blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
} }
class ThirdPartyDomStorageAccessMetricsObserverBrowserTest class ThirdPartyDomStorageAccessMetricsObserverBrowserTest
...@@ -509,6 +547,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -509,6 +547,9 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount("Blink.UseCounter.Features", test_case, histogram_tester.ExpectBucketCount("Blink.UseCounter.Features", test_case,
0); 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccess, 0);
} }
} }
...@@ -531,7 +572,85 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, ...@@ -531,7 +572,85 @@ IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
histogram_tester.ExpectBucketCount("Blink.UseCounter.Features", test_case, histogram_tester.ExpectBucketCount("Blink.UseCounter.Features", test_case,
1); 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccess, 1);
} }
} }
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
ThirdPartyFrameWithActivationReported) {
base::HistogramTester histogram_tester;
NavigateToPageWithFrame("a.com");
NavigateFrameTo("b.com", "/");
TriggerFrameActivation();
NavigateToUntrackedUrl();
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyActivation, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccessAndActivation, 0);
}
IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest,
FirstPartyFrameWithActivationNotReported) {
base::HistogramTester histogram_tester;
NavigateToPageWithFrame("a.com");
NavigateFrameTo("a.com", "/");
TriggerFrameActivation();
NavigateToUntrackedUrl();
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyActivation, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccessAndActivation, 0);
}
IN_PROC_BROWSER_TEST_F(
ThirdPartyMetricsObserverBrowserTest,
ThirdPartyFrameWithAccessAndActivationOnDifferentThirdParties) {
base::HistogramTester histogram_tester;
NavigateToPageWithFrame("a.com");
NavigateFrameTo("b.com", "/");
TriggerFrameActivation();
NavigateFrameTo("c.com", "/set-cookie?thirdparty=1;SameSite=None;Secure");
NavigateToUntrackedUrl();
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyActivation, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccessAndActivation, 0);
}
IN_PROC_BROWSER_TEST_F(
ThirdPartyMetricsObserverBrowserTest,
ThirdPartyFrameWithAccessAndActivationOnSameThirdParties) {
base::HistogramTester histogram_tester;
NavigateToPageWithFrame("a.com");
NavigateFrameTo("b.com", "/set-cookie?thirdparty=1;SameSite=None;Secure");
TriggerFrameActivation();
NavigateToUntrackedUrl();
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyActivation, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features", blink::mojom::WebFeature::kThirdPartyAccess,
1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyAccessAndActivation, 1);
}
} // namespace } // namespace
...@@ -3022,6 +3022,9 @@ enum WebFeature { ...@@ -3022,6 +3022,9 @@ enum WebFeature {
kAddressSpacePrivateEmbeddedInPublicNonSecureContext = 3695, kAddressSpacePrivateEmbeddedInPublicNonSecureContext = 3695,
kAddressSpacePrivateEmbeddedInUnknownSecureContext = 3696, kAddressSpacePrivateEmbeddedInUnknownSecureContext = 3696,
kAddressSpacePrivateEmbeddedInUnknownNonSecureContext = 3697, kAddressSpacePrivateEmbeddedInUnknownNonSecureContext = 3697,
kThirdPartyAccess = 3698,
kThirdPartyActivation = 3699,
kThirdPartyAccessAndActivation = 3700,
// Add new features immediately above this line. Don't change assigned // Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots. // numbers of any item, and don't reuse removed slots.
......
...@@ -29583,6 +29583,9 @@ Called by update_use_counter_feature_enum.py.--> ...@@ -29583,6 +29583,9 @@ Called by update_use_counter_feature_enum.py.-->
<int value="3696" label="AddressSpacePrivateEmbeddedInUnknownSecureContext"/> <int value="3696" label="AddressSpacePrivateEmbeddedInUnknownSecureContext"/>
<int value="3697" <int value="3697"
label="AddressSpacePrivateEmbeddedInUnknownNonSecureContext"/> label="AddressSpacePrivateEmbeddedInUnknownNonSecureContext"/>
<int value="3698" label="ThirdPartyAccess"/>
<int value="3699" label="ThirdPartyActivation"/>
<int value="3700" label="ThirdPartyAccessAndActivation"/>
</enum> </enum>
<enum name="FeaturePolicyAllowlistType"> <enum name="FeaturePolicyAllowlistType">
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