From 0c3d1b35a2e9aa2826a0bf4c7e05d646719c6a30 Mon Sep 17 00:00:00 2001 From: Charlie Harrison Date: Fri, 19 Apr 2019 19:25:07 +0000 Subject: [PATCH] Remove the ad delay throttle This experiment has been disabled for a while. It should be pretty easy to reland if we decide we want to do it. Bug: 829042 Change-Id: I273d7a757312f1628ce3878e266311455eb73eb1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1574281 Commit-Queue: Charlie Harrison Reviewed-by: Josh Karlin Reviewed-by: Avi Drissman Auto-Submit: Charlie Harrison Cr-Commit-Position: refs/heads/master@{#652601} --- .../ad_delay_browsertest.cc | 222 ------- .../url_loader_throttle_provider_impl.cc | 14 - .../url_loader_throttle_provider_impl.h | 4 - chrome/test/BUILD.gn | 1 - .../content/common/BUILD.gn | 3 - .../content/common/ad_delay_throttle.cc | 213 ------- .../content/common/ad_delay_throttle.h | 178 ------ .../common/ad_delay_throttle_unittest.cc | 572 ------------------ .../content/renderer/BUILD.gn | 2 - .../ad_delay_renderer_metadata_provider.cc | 54 -- .../ad_delay_renderer_metadata_provider.h | 44 -- .../core/common/common_features.cc | 5 - 12 files changed, 1312 deletions(-) delete mode 100644 chrome/browser/subresource_filter/ad_delay_browsertest.cc delete mode 100644 components/subresource_filter/content/common/ad_delay_throttle.cc delete mode 100644 components/subresource_filter/content/common/ad_delay_throttle.h delete mode 100644 components/subresource_filter/content/common/ad_delay_throttle_unittest.cc delete mode 100644 components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.cc delete mode 100644 components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h diff --git a/chrome/browser/subresource_filter/ad_delay_browsertest.cc b/chrome/browser/subresource_filter/ad_delay_browsertest.cc deleted file mode 100644 index 361dfc5efe3976..00000000000000 --- a/chrome/browser/subresource_filter/ad_delay_browsertest.cc +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/metrics/field_trial_params.h" -#include "base/strings/stringprintf.h" -#include "base/test/scoped_feature_list.h" -#include "base/timer/elapsed_timer.h" -#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/subresource_filter/content/common/ad_delay_throttle.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_navigation_observer.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -class AdDelayBrowserTest - : public subresource_filter::SubresourceFilterBrowserTest { - public: - AdDelayBrowserTest() : subresource_filter::SubresourceFilterBrowserTest() {} - ~AdDelayBrowserTest() override {} - - void SetUp() override { - secure_server_ = std::make_unique( - net::EmbeddedTestServer::TYPE_HTTPS); - secure_server_->AddDefaultHandlers(GetChromeTestDataDir()); - - scoped_features_.InitAndEnableFeatureWithParameters( - subresource_filter::kDelayUnsafeAds, - {{subresource_filter::kInsecureDelayParam, DelayParamToUse()}, - {subresource_filter::kNonIsolatedDelayParam, DelayParamToUse()}}); - subresource_filter::SubresourceFilterBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - ASSERT_TRUE(secure_server_->Start()); - subresource_filter::SubresourceFilterBrowserTest::SetUpOnMainThread(); - host_resolver()->ClearRules(); - } - - // Calls fetchResources on the page, which issues fetch()es for two resources. - // - // Returns the name of the file whose fetch complete event triggered the - // callback. - // - If |policy| is kBothFetches, the returned file will be the last file - // loaded. - // - If |policy| is kOneFetch, the returned file will be the first file - // loaded. - enum class WaitForPolicy { kOneFetch, kBothFetches }; - std::string FetchResources(const content::ToRenderFrameHost& adapter, - WaitForPolicy policy) { - std::string ret; - EXPECT_TRUE(content::ExecuteScriptAndExtractString( - adapter, - base::StringPrintf( - "fetchResources(%s);", - policy == WaitForPolicy::kBothFetches ? "true" : "false"), - &ret)); - return ret; - } - - content::WebContents* GetWebContents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - content::RenderFrameHost* AppendFrameAndWait( - const content::ToRenderFrameHost& adapter, - const GURL& url) { - content::RenderFrameHost* rfh = adapter.render_frame_host(); - const char kScript[] = R"( - var frame = document.createElement('iframe'); - frame.src = "%s"; - document.body.appendChild(frame);)"; - std::string script = base::StringPrintf(kScript, url.spec().c_str()); - - content::TestNavigationObserver nav(GetWebContents(), 1); - EXPECT_TRUE(content::ExecuteScript(rfh, script)); - nav.Wait(); - EXPECT_TRUE(nav.last_navigation_succeeded()) << nav.last_net_error_code(); - return content::FrameMatchingPredicate( - GetWebContents(), - base::BindRepeating(&content::FrameHasSourceUrl, url)); - } - - base::TimeDelta GetExpectedDelay() const { - return base::TimeDelta::FromMilliseconds( - base::GetFieldTrialParamByFeatureAsInt( - subresource_filter::kDelayUnsafeAds, - subresource_filter::kInsecureDelayParam, - subresource_filter::AdDelayThrottle::kDefaultDelay - .InMilliseconds())); - } - - protected: - // 10 minutes. - virtual std::string DelayParamToUse() { return "600000"; } - - std::unique_ptr secure_server_; - - private: - base::test::ScopedFeatureList scoped_features_; -}; - -class MinimalAdDelayBrowserTest : public AdDelayBrowserTest { - std::string DelayParamToUse() override { return "100"; } -}; - -IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, NoAd_NoDelay) { - GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ui_test_utils::NavigateToURL(browser(), url); - - base::ElapsedTimer timer; - FetchResources(GetWebContents(), WaitForPolicy::kBothFetches); - EXPECT_GT(GetExpectedDelay(), timer.Elapsed()); -} - -IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, InsecureAdRequest_IsDelayed) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ui_test_utils::NavigateToURL(browser(), url); - - // If the included_script.js is delayed, assert that the - // included_allowed_script will always load before it. Because the allowed - // script is fetched second, this is a reasonably strong statement. - base::ElapsedTimer timer; - std::string first_resource = - FetchResources(GetWebContents(), WaitForPolicy::kOneFetch); - EXPECT_GE(GetExpectedDelay(), timer.Elapsed()); - EXPECT_EQ("included_allowed_script.js", first_resource); -} - -IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, SecureAdRequest_NoDelay) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(secure_server_->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ui_test_utils::NavigateToURL(browser(), url); - - base::ElapsedTimer timer; - std::string first_resource = - FetchResources(GetWebContents(), WaitForPolicy::kBothFetches); - EXPECT_GT(GetExpectedDelay(), timer.Elapsed()); -} - -IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, NonIsolatedAdRequest_IsDelayed) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(secure_server_->GetURL("/title1.html")); - ui_test_utils::NavigateToURL(browser(), url); - - content::RenderFrameHost* subframe = AppendFrameAndWait( - GetWebContents(), - secure_server_->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ASSERT_TRUE(subframe); - - base::ElapsedTimer timer; - std::string first_resource = - FetchResources(subframe, WaitForPolicy::kOneFetch); - EXPECT_GE(GetExpectedDelay(), timer.Elapsed()); - EXPECT_EQ("included_allowed_script.js", first_resource); -} - -IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, IsolatedAdRequest_NoDelay) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(embedded_test_server()->GetURL("/title1.html")); - ui_test_utils::NavigateToURL(browser(), url); - - content::RenderFrameHost* subframe = AppendFrameAndWait( - GetWebContents(), - secure_server_->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ASSERT_TRUE(subframe); - - base::ElapsedTimer timer; - FetchResources(subframe, WaitForPolicy::kBothFetches); - EXPECT_GT(GetExpectedDelay(), timer.Elapsed()); -} - -IN_PROC_BROWSER_TEST_F(MinimalAdDelayBrowserTest, AdRequest_IsNotBlackholed) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_multiple_fetches.html")); - ui_test_utils::NavigateToURL(browser(), url); - // The test succeeds if it does not time out. - base::ElapsedTimer timer; - FetchResources(GetWebContents(), WaitForPolicy::kBothFetches); - EXPECT_LE(GetExpectedDelay(), timer.Elapsed()); -} - -IN_PROC_BROWSER_TEST_F(MinimalAdDelayBrowserTest, SyncXHRAd) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(embedded_test_server()->GetURL("/title1.html")); - ui_test_utils::NavigateToURL(browser(), url); - std::string script = R"( - var request = new XMLHttpRequest(); - request.open('GET', '/subresource_filter/included_script.js', false); - request.send(null); - )"; - base::ElapsedTimer timer; - EXPECT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), script.c_str())); - subresource_filter::AdDelayThrottle::Factory factory; - EXPECT_LE(factory.insecure_delay(), timer.Elapsed()); -} diff --git a/chrome/renderer/url_loader_throttle_provider_impl.cc b/chrome/renderer/url_loader_throttle_provider_impl.cc index dc02ae1d21412e..66054056e78077 100644 --- a/chrome/renderer/url_loader_throttle_provider_impl.cc +++ b/chrome/renderer/url_loader_throttle_provider_impl.cc @@ -22,7 +22,6 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_throttle_manager.h" #include "components/safe_browsing/features.h" #include "components/safe_browsing/renderer/renderer_url_loader_throttle.h" -#include "components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h" #include "content/public/common/content_features.h" #include "content/public/common/service_names.mojom.h" #include "content/public/renderer/render_frame.h" @@ -260,19 +259,6 @@ URLLoaderThrottleProviderImpl::CreateThrottles( } #endif - // Initialize the factory here rather than in the constructor, since metrics - // does not support registering field trials (as opposed to Features) before - // Blink is initialized (after this class). - if (!ad_delay_factory_) { - ad_delay_factory_ = - std::make_unique(); - } - if (auto ad_throttle = ad_delay_factory_->MaybeCreate( - std::make_unique( - request, type_, render_frame_id))) { - throttles.push_back(std::move(ad_throttle)); - } - throttles.push_back(std::make_unique( ChromeRenderThreadObserver::is_incognito_process(), ChromeRenderThreadObserver::GetDynamicParams())); diff --git a/chrome/renderer/url_loader_throttle_provider_impl.h b/chrome/renderer/url_loader_throttle_provider_impl.h index f2b78d682e5cda..f58e4613d9a5fe 100644 --- a/chrome/renderer/url_loader_throttle_provider_impl.h +++ b/chrome/renderer/url_loader_throttle_provider_impl.h @@ -10,7 +10,6 @@ #include "base/threading/thread_checker.h" #include "components/safe_browsing/common/safe_browsing.mojom.h" -#include "components/subresource_filter/content/common/ad_delay_throttle.h" #include "content/public/renderer/url_loader_throttle_provider.h" #include "extensions/buildflags/buildflags.h" @@ -48,9 +47,6 @@ class URLLoaderThrottleProviderImpl // general use. URLLoaderThrottleProviderImpl(const URLLoaderThrottleProviderImpl& other); - std::unique_ptr - ad_delay_factory_; - content::URLLoaderThrottleProviderType type_; ChromeContentRendererClient* const chrome_content_renderer_client_; diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index e047b2aeb297e8..aa10453dad3018 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn @@ -914,7 +914,6 @@ test("browser_tests") { "../browser/ssl/ssl_client_certificate_selector_test.h", "../browser/ssl/typed_navigation_timing_throttle_browsertest.cc", "../browser/storage/durable_storage_browsertest.cc", - "../browser/subresource_filter/ad_delay_browsertest.cc", "../browser/subresource_filter/ad_tagging_browsertest.cc", "../browser/subresource_filter/ruleset_browsertest.cc", "../browser/subresource_filter/subresource_filter_browser_test_harness.cc", diff --git a/components/subresource_filter/content/common/BUILD.gn b/components/subresource_filter/content/common/BUILD.gn index 71f460b3efff44..a2e6e5fc02c915 100644 --- a/components/subresource_filter/content/common/BUILD.gn +++ b/components/subresource_filter/content/common/BUILD.gn @@ -4,8 +4,6 @@ static_library("common") { sources = [ - "ad_delay_throttle.cc", - "ad_delay_throttle.h", "ruleset_dealer.cc", "ruleset_dealer.h", "subresource_filter_message_generator.cc", @@ -27,7 +25,6 @@ static_library("common") { source_set("unit_tests") { testonly = true sources = [ - "ad_delay_throttle_unittest.cc", "ruleset_dealer_unittest.cc", ] deps = [ diff --git a/components/subresource_filter/content/common/ad_delay_throttle.cc b/components/subresource_filter/content/common/ad_delay_throttle.cc deleted file mode 100644 index 594d979002b4d9..00000000000000 --- a/components/subresource_filter/content/common/ad_delay_throttle.cc +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/subresource_filter/content/common/ad_delay_throttle.h" - -#include -#include - -#include "base/bind.h" -#include "base/feature_list.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/field_trial_params.h" -#include "base/metrics/histogram_macros.h" -#include "base/sequenced_task_runner.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/time/default_tick_clock.h" -#include "base/time/tick_clock.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "url/gurl.h" -#include "url/url_constants.h" - -namespace subresource_filter { - -namespace { - -void LogSecureInfo(AdDelayThrottle::SecureInfo info) { - UMA_HISTOGRAM_ENUMERATION("Ads.Features.ResourceIsSecure", info); -} - -class InsecureCondition : public AdDelayThrottle::DeferCondition { - public: - InsecureCondition(base::TimeDelta delay, - AdDelayThrottle::MetadataProvider* provider) - : DeferCondition(delay, provider) {} - ~InsecureCondition() override { - if (provider()->IsAdRequest()) { - LogSecureInfo(was_condition_ever_satisfied() - ? AdDelayThrottle::SecureInfo::kInsecureAd - : AdDelayThrottle::SecureInfo::kSecureAd); - } else { - LogSecureInfo(was_condition_ever_satisfied() - ? AdDelayThrottle::SecureInfo::kInsecureNonAd - : AdDelayThrottle::SecureInfo::kSecureNonAd); - } - } - - private: - // DeferCondition: - bool IsConditionSatisfied(const GURL& url) override { - // Note: this should probably be using content::IsOriginSecure which - // accounts for things like whitelisted origins, localhost, etc. This isn't - // used here because that function is quite expensive for insecure schemes, - // involving many allocations and string scans. - return url.SchemeIs(url::kHttpScheme); - } -}; - -class NonIsolatedCondition : public AdDelayThrottle::DeferCondition { - public: - NonIsolatedCondition(base::TimeDelta delay, - AdDelayThrottle::MetadataProvider* provider) - : DeferCondition(delay, provider) {} - ~NonIsolatedCondition() override { - if (provider()->IsAdRequest()) { - UMA_HISTOGRAM_ENUMERATION( - "Ads.Features.AdResourceIsIsolated", - was_condition_ever_satisfied() - ? AdDelayThrottle::IsolatedInfo::kNonIsolatedAd - : AdDelayThrottle::IsolatedInfo::kIsolatedAd); - } - } - - private: - // DeferCondition: - bool IsConditionSatisfied(const GURL& url) override { - return provider()->RequestIsInNonIsolatedSubframe(); - } -}; - -} // namespace - -AdDelayThrottle::DeferCondition::DeferCondition( - base::TimeDelta delay, - AdDelayThrottle::MetadataProvider* provider) - : delay_(delay), provider_(provider) { - DCHECK(provider); -} -AdDelayThrottle::DeferCondition::~DeferCondition() = default; - -bool AdDelayThrottle::DeferCondition::ShouldDefer(const GURL& url) { - if (was_condition_applied_) { - DCHECK(was_condition_ever_satisfied_); - return false; - } - was_condition_ever_satisfied_ |= IsConditionSatisfied(url); - return was_condition_ever_satisfied_; -} - -// The request will be deferred. Returns the amount of time to defer. -base::TimeDelta AdDelayThrottle::DeferCondition::OnReadyToDefer() { - DCHECK(!was_condition_applied_); - DCHECK(was_condition_ever_satisfied_); - was_condition_applied_ = true; - return delay_; -} - -constexpr base::TimeDelta AdDelayThrottle::kDefaultDelay; - -AdDelayThrottle::Factory::Factory() - : delay_enabled_(base::FeatureList::IsEnabled(kAdTagging) && - base::FeatureList::IsEnabled(kDelayUnsafeAds)), - insecure_delay_(base::TimeDelta::FromMilliseconds( - delay_enabled_ ? base::GetFieldTrialParamByFeatureAsInt( - kDelayUnsafeAds, - kInsecureDelayParam, - kDefaultDelay.InMilliseconds()) - : 0)), - non_isolated_delay_(base::TimeDelta::FromMilliseconds( - delay_enabled_ ? base::GetFieldTrialParamByFeatureAsInt( - kDelayUnsafeAds, - kNonIsolatedDelayParam, - kDefaultDelay.InMilliseconds()) - : 0)) {} - -AdDelayThrottle::Factory::~Factory() = default; - -std::unique_ptr AdDelayThrottle::Factory::MaybeCreate( - std::unique_ptr provider) const { - DCHECK(provider); - return base::WrapUnique(new AdDelayThrottle(std::move(provider), this)); -} - -AdDelayThrottle::~AdDelayThrottle() { - if (!expected_delay_.is_zero()) { - UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay", actual_delay_); - UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay.Expected", - expected_delay_); - UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay.Queuing", - actual_delay_ - expected_delay_); - } -} - -void AdDelayThrottle::DetachFromCurrentSequence() { - // The throttle is moving to another thread. Ensure this is done before any - // weak pointers are created. - DCHECK(!weak_factory_.HasWeakPtrs()); -} - -void AdDelayThrottle::WillStartRequest(network::ResourceRequest* request, - bool* defer) { - *defer = MaybeDefer(request->url); -} - -void AdDelayThrottle::WillRedirectRequest( - net::RedirectInfo* redirect_info, - const network::ResourceResponseHead& /* response_head */, - bool* defer, - std::vector* /* to_be_removed_headers */, - net::HttpRequestHeaders* /* modified_headers */) { - // Note: some MetadataProviders may not be able to distinguish requests that - // are only tagged as ads after a redirect. - *defer = MaybeDefer(redirect_info->new_url); -} - -bool AdDelayThrottle::MaybeDefer(const GURL& url) { - // Check for condition matching before checking if the feature is enabled, to - // ensure metrics can be reported. - std::vector matched_conditions; - for (auto& condition : defer_conditions_) { - if (condition->ShouldDefer(url)) - matched_conditions.push_back(condition.get()); - } - - if (!delay_enabled_ || matched_conditions.empty() || - !provider_->IsAdRequest()) { - return false; - } - - base::TimeDelta delay; - for (DeferCondition* condition : matched_conditions) { - delay += condition->OnReadyToDefer(); - } - // TODO(csharrison): Consider logging to the console here that Chrome - // delayed this request. - expected_delay_ += delay; - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&AdDelayThrottle::Resume, weak_factory_.GetWeakPtr(), - tick_clock_->NowTicks()), - delay); - return true; -} - -void AdDelayThrottle::Resume(base::TimeTicks defer_start) { - actual_delay_ += tick_clock_->NowTicks() - defer_start; - delegate_->Resume(); -} - -AdDelayThrottle::AdDelayThrottle(std::unique_ptr provider, - const AdDelayThrottle::Factory* factory) - : provider_(std::move(provider)), - tick_clock_(base::DefaultTickClock::GetInstance()), - delay_enabled_(factory->delay_enabled()), - weak_factory_(this) { - defer_conditions_.emplace_back(std::make_unique( - factory->insecure_delay(), provider_.get())); - defer_conditions_.emplace_back(std::make_unique( - factory->non_isolated_delay(), provider_.get())); -} - -} // namespace subresource_filter diff --git a/components/subresource_filter/content/common/ad_delay_throttle.h b/components/subresource_filter/content/common/ad_delay_throttle.h deleted file mode 100644 index 03643fd11c620a..00000000000000 --- a/components/subresource_filter/content/common/ad_delay_throttle.h +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_ -#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_ - -#include - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "content/public/common/url_loader_throttle.h" -#include "services/network/public/cpp/resource_request.h" - -class GURL; - -namespace base { -class TickClock; -} // namespace base - -namespace subresource_filter { - -class DeferCondition; - -// This class delays ad requests satisfying certain conditions. -// - The ad is insecure (e.g. uses http). -// TODO(csharrison): Add delays for when the request is in a same-origin iframe. -class AdDelayThrottle : public content::URLLoaderThrottle { - public: - static constexpr base::TimeDelta kDefaultDelay = - base::TimeDelta::FromMilliseconds(50); - - class MetadataProvider { - public: - virtual ~MetadataProvider() {} - virtual bool IsAdRequest() = 0; - - // Whether the request is taking place in a non-isolated (e.g. same-domain) - // iframe. Should default to false if the isolation status is unknown. - virtual bool RequestIsInNonIsolatedSubframe() = 0; - }; - - // Mainly used for caching values that we don't want to compute for every - // resource request. - class Factory { - public: - Factory(); - ~Factory(); - - std::unique_ptr MaybeCreate( - std::unique_ptr provider) const; - - base::TimeDelta insecure_delay() const { return insecure_delay_; } - base::TimeDelta non_isolated_delay() const { return non_isolated_delay_; } - bool delay_enabled() const { return delay_enabled_; } - - private: - const bool delay_enabled_ = false; - const base::TimeDelta insecure_delay_; - const base::TimeDelta non_isolated_delay_; - - DISALLOW_COPY_AND_ASSIGN(Factory); - }; - - // This enum backs a histogram. Make sure to only append elements, and update - // enums.xml with new values. - enum class SecureInfo { - // Ad that was loaded securely (e.g. using https). - kSecureAd = 0, - - // Ad that was loaded insecurely (e.g. at least one request through http). - kInsecureAd = 1, - - kSecureNonAd = 2, - kInsecureNonAd = 3, - - // Add new elements above kLast. - kMaxValue = kInsecureNonAd - }; - - // This enum backs a histogram. Make sure to only append elements, and update - // enums.xml with new values. - enum class IsolatedInfo { - // Ad that was loaded isolated from the top-level page (e.g. from a - // cross-domain iframe). - kIsolatedAd = 0, - - // Ad loaded from a non-isolated context. - kNonIsolatedAd = 1, - - // Add new elements above kLast. - kMaxValue = kNonIsolatedAd - }; - // The AdDelayThrottle has multiple possible conditions which can cause - // delays. These conditions will subclass DeferCondition and override - // IsConditionSatisfied. - class DeferCondition { - public: - DeferCondition(base::TimeDelta delay, - AdDelayThrottle::MetadataProvider* provider); - virtual ~DeferCondition(); - - bool ShouldDefer(const GURL& url); - - // The request will be deferred. Returns the amount of time to defer. Should - // be called at most once after ShouldDefer returns true. - base::TimeDelta OnReadyToDefer(); - - bool was_condition_ever_satisfied() const { - return was_condition_ever_satisfied_; - } - - AdDelayThrottle::MetadataProvider* provider() { return provider_; } - - protected: - virtual bool IsConditionSatisfied(const GURL& url) = 0; - - private: - base::TimeDelta delay_; - - // Must outlive this object. Will always be non-nullptr. - AdDelayThrottle::MetadataProvider* provider_; - - bool was_condition_applied_ = false; - bool was_condition_ever_satisfied_ = false; - DISALLOW_COPY_AND_ASSIGN(DeferCondition); - }; - - ~AdDelayThrottle() override; - - void set_tick_clock_for_testing(const base::TickClock* tick_clock) { - tick_clock_ = tick_clock; - } - - private: - // content::URLLoaderThrottle: - void DetachFromCurrentSequence() override; - void WillStartRequest(network::ResourceRequest* request, - bool* defer) override; - void WillRedirectRequest(net::RedirectInfo* redirect_info, - const network::ResourceResponseHead& response_head, - bool* defer, - std::vector* to_be_removed_headers, - net::HttpRequestHeaders* modified_headers) override; - - // Returns whether the request to |url| should be deferred. - bool MaybeDefer(const GURL& url); - void Resume(base::TimeTicks defer_start); - - AdDelayThrottle(std::unique_ptr provider, - const Factory* factory); - - // Will never be nullptr. - std::unique_ptr provider_; - - // Must be destroyed before |provider_|. - std::vector> defer_conditions_; - - // Must never be nullptr. - const base::TickClock* tick_clock_; - - // Will be zero if no delay occurs. - base::TimeDelta expected_delay_; - base::TimeDelta actual_delay_; - - // Whether to actually delay the request. If set to false, will operate in a - // dry-run style mode that only logs metrics. - const bool delay_enabled_ = false; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AdDelayThrottle); -}; - -} // namespace subresource_filter - -#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_ diff --git a/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc b/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc deleted file mode 100644 index d98014080ade69..00000000000000 --- a/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/subresource_filter/content/common/ad_delay_throttle.h" - -#include -#include -#include -#include - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_refptr.h" -#include "base/metrics/field_trial_params.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/scoped_task_environment.h" -#include "base/test/simple_test_tick_clock.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "content/public/test/throttling_url_loader_test_util.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/public/mojom/url_loader.mojom.h" -#include "services/network/test/test_url_loader_client.h" -#include "services/network/test/test_url_loader_factory.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace subresource_filter { - -// Use a TestURLLoaderFactory with a real ThrottlingURLLoader + the delay -// throttle. -class AdDelayThrottleTest : public testing::Test { - public: - AdDelayThrottleTest() - : scoped_environment_( - base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), - client_(std::make_unique()), - shared_factory_( - base::MakeRefCounted( - &loader_factory_)) { - scoped_ad_tagging_.InitAndEnableFeature(kAdTagging); - } - ~AdDelayThrottleTest() override {} - - void SetUp() override { - scoped_features_.InitAndEnableFeature(kDelayUnsafeAds); - } - - protected: - std::unique_ptr CreateLoaderAndStart( - const GURL& url, - std::unique_ptr throttle) { - network::ResourceRequest request; - request.url = url; - std::vector> throttles; - throttles.push_back(std::move(throttle)); - auto loader = content::CreateThrottlingLoaderAndStart( - shared_factory_, std::move(throttles), 0 /* routing_id */, - 0 /* request_id */, 0 /* options */, &request, client_.get(), - TRAFFIC_ANNOTATION_FOR_TESTS, base::ThreadTaskRunnerHandle::Get()); - return loader; - } - - base::TimeDelta GetExpectedDelay(const char* param) const { - return base::TimeDelta::FromMilliseconds( - base::GetFieldTrialParamByFeatureAsInt( - kDelayUnsafeAds, param, - AdDelayThrottle::kDefaultDelay.InMilliseconds())); - } - - base::test::ScopedTaskEnvironment scoped_environment_; - std::unique_ptr client_; - network::TestURLLoaderFactory loader_factory_; - - base::test::ScopedFeatureList scoped_features_; - - private: - // Use a separate ScopedFeatureList to enable ad tagging, as - // InitAndEnableFeaturesWithParameters does not support enabling multiple - // features. - base::test::ScopedFeatureList scoped_ad_tagging_; - scoped_refptr shared_factory_; - - DISALLOW_COPY_AND_ASSIGN(AdDelayThrottleTest); -}; - -// Metadata provider that by default, provides metadata indicating that the -// request is an isolated ad. -class MockMetadataProvider : public AdDelayThrottle::MetadataProvider { - public: - MockMetadataProvider() {} - - void set_is_ad_request(bool is_ad_request) { is_ad_request_ = is_ad_request; } - void set_is_non_isolated(bool is_non_isolated) { - is_non_isolated_ = is_non_isolated; - } - - // AdDelayThrottle::MetadataProvider: - bool IsAdRequest() override { return is_ad_request_; } - bool RequestIsInNonIsolatedSubframe() override { return is_non_isolated_; } - - private: - bool is_ad_request_ = true; - bool is_non_isolated_ = false; - - DISALLOW_COPY_AND_ASSIGN(MockMetadataProvider); -}; - -// This test harness is identical to the AdDelayThrottleTest but is -// parameterized by a bool that enables or disables the feature wholesale. -class AdDelayThrottleEnabledParamTest - : public AdDelayThrottleTest, - public ::testing::WithParamInterface { - void SetUp() override { - if (GetParam()) { - scoped_features_.InitAndEnableFeature(kDelayUnsafeAds); - } else { - scoped_features_.InitAndDisableFeature(kDelayUnsafeAds); - } - } -}; - -TEST_F(AdDelayThrottleTest, NoFeature_NoDelay) { - base::test::ScopedFeatureList scoped_disable; - scoped_disable.InitAndDisableFeature(kDelayUnsafeAds); - - AdDelayThrottle::Factory factory; - auto throttle = factory.MaybeCreate(std::make_unique()); - EXPECT_NE(nullptr, throttle); - std::string url = "http://example.test/ad.js"; - loader_factory_.AddResponse(url, "var ads = 1;"); - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(url), std::move(throttle)); - scoped_environment_.RunUntilIdle(); - - EXPECT_TRUE(client_->has_received_completion()); -} - -TEST_F(AdDelayThrottleTest, NoAdTagging_NoDelay) { - base::test::ScopedFeatureList scoped_disable; - scoped_disable.InitAndDisableFeature(kAdTagging); - base::test::ScopedFeatureList scoped_params; - scoped_params.InitAndEnableFeatureWithParameters( - kDelayUnsafeAds, - {{kInsecureDelayParam, "50"}, {kNonIsolatedDelayParam, "100"}}); - - AdDelayThrottle::Factory factory; - auto throttle = factory.MaybeCreate(std::make_unique()); - EXPECT_NE(nullptr, throttle); - std::string url = "http://example.test/ad.js"; - loader_factory_.AddResponse(url, "var ads = 1;"); - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(url), std::move(throttle)); - scoped_environment_.RunUntilIdle(); - - EXPECT_TRUE(client_->has_received_completion()); - EXPECT_FALSE(base::FieldTrialList::IsTrialActive( - base::FeatureList::GetFieldTrial(kDelayUnsafeAds)->trial_name())); -} - -TEST_F(AdDelayThrottleTest, AdDelay) { - enum class IsNonIsolated { kYes, kNo }; - enum class IsAd { kYes, kNo }; - enum class WillFinish { kYes, kNo }; - struct TestCase { - const char* first_url; - const char* redirect_url; // nullptr if no redirect. - IsNonIsolated is_non_isolated; - IsAd is_ad; - int fast_forward_ms; - WillFinish will_finish; - } kTestCases[] = { - // Isolated and secure -> no delay. - {"https://ad.test/", nullptr, IsNonIsolated::kNo, IsAd::kYes, 0, - WillFinish::kYes}, - - // Isolated and insecure -> delays 50ms. - {"http://ad.test/", nullptr, IsNonIsolated::kNo, IsAd::kYes, 49, - WillFinish::kNo}, - {"http://ad.test/", nullptr, IsNonIsolated::kNo, IsAd::kYes, 50, - WillFinish::kYes}, - {"http://ad.test/", nullptr, IsNonIsolated::kNo, IsAd::kNo, 0, - WillFinish::kYes}, - - // Non-isolated and secure -> delays 100ms. - {"https://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kYes, 99, - WillFinish::kNo}, - {"https://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kYes, 100, - WillFinish::kYes}, - {"https://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kNo, 0, - WillFinish::kYes}, - - // Non-isolated and insecure -> delays 150ms. - {"http://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kYes, 149, - WillFinish::kNo}, - {"http://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kYes, 150, - WillFinish::kYes}, - {"http://ad.test/", nullptr, IsNonIsolated::kYes, IsAd::kNo, 0, - WillFinish::kYes}, - - // Isolated and insecure redirect -> delays 50ms. - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kYes, - 49, WillFinish::kNo}, - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kYes, - 50, WillFinish::kYes}, - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kNo, 0, - WillFinish::kYes}, - - // Non-isolated and insecure redirect -> delays 150ms total. - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kYes, IsAd::kYes, - 149, WillFinish::kNo}, - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kYes, IsAd::kYes, - 150, WillFinish::kYes}, - {"https://ad.test/", "http://ad.test/", IsNonIsolated::kYes, IsAd::kNo, 0, - WillFinish::kYes}, - - // Isolated + insecure with insecure redirect -> delays 50ms only. - {"http://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kYes, 49, - WillFinish::kNo}, - {"http://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kYes, 50, - WillFinish::kYes}, - {"http://ad.test/", "http://ad.test/", IsNonIsolated::kNo, IsAd::kNo, 0, - WillFinish::kYes}, - }; - // Initialize delays so insecure and non-isolated are not equal. - base::test::ScopedFeatureList scoped_params; - scoped_params.InitAndEnableFeatureWithParameters( - kDelayUnsafeAds, - {{kInsecureDelayParam, "50"}, {kNonIsolatedDelayParam, "100"}}); - for (const auto& test : kTestCases) { - bool is_ad = test.is_ad == IsAd::kYes; - bool is_non_isolated = test.is_non_isolated == IsNonIsolated::kYes; - SCOPED_TRACE(testing::Message() - << test.first_url << " -> " - << (test.redirect_url ? test.redirect_url : "") - << " is_ad = " << is_ad - << " is_non_isolated = " << is_non_isolated - << " fast_forward_ms = " << test.fast_forward_ms); - AdDelayThrottle::Factory factory; - client_ = std::make_unique(); - auto provider = std::make_unique(); - provider->set_is_non_isolated(is_non_isolated); - provider->set_is_ad_request(is_ad); - auto throttle = factory.MaybeCreate(std::move(provider)); - - ASSERT_TRUE(test.first_url); - if (test.redirect_url) { - net::RedirectInfo redirect_info; - redirect_info.status_code = 301; - redirect_info.new_url = GURL(test.redirect_url); - network::TestURLLoaderFactory::Redirects redirects{ - {redirect_info, network::ResourceResponseHead()}}; - loader_factory_.AddResponse( - GURL(test.first_url), network::ResourceResponseHead(), "foo", - network::URLLoaderCompletionStatus(), redirects); - } else { - loader_factory_.AddResponse(test.first_url, "foo"); - } - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(test.first_url), std::move(throttle)); - scoped_environment_.RunUntilIdle(); - scoped_environment_.FastForwardBy( - base::TimeDelta::FromMilliseconds(test.fast_forward_ms)); - EXPECT_EQ(test.will_finish == WillFinish::kYes, - client_->has_received_completion()); - } -} - -TEST_F(AdDelayThrottleTest, DestroyBeforeDelay) { - AdDelayThrottle::Factory factory; - auto throttle = factory.MaybeCreate(std::make_unique()); - EXPECT_NE(nullptr, throttle); - std::string url = "http://example.test/ad.js"; - loader_factory_.AddResponse(url, "var ads = 1;"); - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(url), std::move(throttle)); - - scoped_environment_.RunUntilIdle(); - EXPECT_FALSE(client_->has_received_completion()); - - loader_client.reset(); - scoped_environment_.FastForwardBy(GetExpectedDelay(kInsecureDelayParam)); -} - -TEST_F(AdDelayThrottleTest, AdDiscoveredAfterRedirect) { - AdDelayThrottle::Factory factory; - auto metadata = std::make_unique(); - MockMetadataProvider* raw_metadata = metadata.get(); - metadata->set_is_ad_request(false); - auto throttle = factory.MaybeCreate(std::move(metadata)); - const GURL url("http://example.test/ad.js"); - - net::RedirectInfo redirect_info; - redirect_info.status_code = 301; - redirect_info.new_url = GURL("http://example2.test/ad.js"); - network::TestURLLoaderFactory::Redirects redirects{ - {redirect_info, network::ResourceResponseHead()}}; - loader_factory_.AddResponse(url, network::ResourceResponseHead(), - "var ads = 1;", - network::URLLoaderCompletionStatus(), redirects); - - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(url), std::move(throttle)); - - raw_metadata->set_is_ad_request(true); - scoped_environment_.RunUntilIdle(); - EXPECT_FALSE(client_->has_received_completion()); - scoped_environment_.FastForwardBy(GetExpectedDelay(kInsecureDelayParam)); - EXPECT_TRUE(client_->has_received_completion()); -} - -// Note: the AdDelayThrottle supports MetadataProviders that update IsAdRequest -// bit after redirects, but not all MetadataProviders necessarily support that. -TEST_F(AdDelayThrottleTest, AdDiscoveredAfterSecureRedirect) { - AdDelayThrottle::Factory factory; - auto metadata = std::make_unique(); - MockMetadataProvider* raw_metadata = metadata.get(); - metadata->set_is_ad_request(false); - auto throttle = factory.MaybeCreate(std::move(metadata)); - - // Request an insecure non-ad request to a secure ad request. Since part of - // the journey was over an insecure channel, the request should be delayed. - const GURL url("http://example.test/ad.js"); - net::RedirectInfo redirect_info; - redirect_info.status_code = 301; - redirect_info.new_url = GURL("https://example.test/ad.js"); - network::TestURLLoaderFactory::Redirects redirects{ - {redirect_info, network::ResourceResponseHead()}}; - loader_factory_.AddResponse(url, network::ResourceResponseHead(), - "var ads = 1;", - network::URLLoaderCompletionStatus(), redirects); - - std::unique_ptr loader_client = - CreateLoaderAndStart(GURL(url), std::move(throttle)); - - raw_metadata->set_is_ad_request(true); - scoped_environment_.RunUntilIdle(); - EXPECT_FALSE(client_->has_received_completion()); - scoped_environment_.FastForwardBy(GetExpectedDelay(kInsecureDelayParam)); - EXPECT_TRUE(client_->has_received_completion()); -} - -TEST_F(AdDelayThrottleTest, DelayMetrics) { - AdDelayThrottle::Factory factory; - const GURL secure_url("https://example.test/ad.js"); - const GURL insecure_url("http://example.test/ad.js"); - loader_factory_.AddResponse(secure_url.spec(), "foo"); - loader_factory_.AddResponse(insecure_url.spec(), "foo"); - - const base::TimeDelta kQueuingDelay = base::TimeDelta::FromMilliseconds(25); - - const char kDelayHistogram[] = "SubresourceFilter.AdDelay.Delay"; - const char kQueuingDelayHistogram[] = - "SubresourceFilter.AdDelay.Delay.Queuing"; - const char kExpectedDelayHistogram[] = - "SubresourceFilter.AdDelay.Delay.Expected"; - { - // Secure isolated ad -> no delay. - base::HistogramTester histograms; - { - auto throttle = - factory.MaybeCreate(std::make_unique()); - throttle->set_tick_clock_for_testing( - scoped_environment_.GetMockTickClock()); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(secure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectTotalCount(kDelayHistogram, 0); - histograms.ExpectTotalCount(kQueuingDelayHistogram, 0); - histograms.ExpectTotalCount(kExpectedDelayHistogram, 0); - } - { - // Insecure isolated non-ad -> no delay. - base::HistogramTester histograms; - { - auto non_ad_metadata = std::make_unique(); - non_ad_metadata->set_is_ad_request(false); - auto throttle = factory.MaybeCreate(std::move(non_ad_metadata)); - throttle->set_tick_clock_for_testing( - scoped_environment_.GetMockTickClock()); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(insecure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectTotalCount(kDelayHistogram, 0); - histograms.ExpectTotalCount(kQueuingDelayHistogram, 0); - histograms.ExpectTotalCount(kExpectedDelayHistogram, 0); - } - - // Use a test clock instead of the scoped task environment's clock because the - // environment executes tasks as soon as it is able, and we want to simulate - // jank by advancing time more than the expected delay. - base::SimpleTestTickClock tick_clock; - { - // Insecure isolated ad -> delay. - base::HistogramTester histograms; - base::TimeDelta expected_delay = GetExpectedDelay(kInsecureDelayParam); - { - auto throttle = - factory.MaybeCreate(std::make_unique()); - throttle->set_tick_clock_for_testing(&tick_clock); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(insecure_url, std::move(throttle)); - - tick_clock.Advance(expected_delay + kQueuingDelay); - scoped_environment_.FastForwardBy(expected_delay + kQueuingDelay); - } - histograms.ExpectUniqueSample( - kDelayHistogram, (expected_delay + kQueuingDelay).InMilliseconds(), 1); - histograms.ExpectUniqueSample(kQueuingDelayHistogram, - kQueuingDelay.InMilliseconds(), 1); - histograms.ExpectUniqueSample(kExpectedDelayHistogram, - expected_delay.InMilliseconds(), 1); - } - { - // Insecure non-isolated ad -> delay. - base::HistogramTester histograms; - base::TimeDelta expected_delay = GetExpectedDelay(kInsecureDelayParam) + - GetExpectedDelay(kNonIsolatedDelayParam); - { - auto non_isolated_metadata = std::make_unique(); - non_isolated_metadata->set_is_non_isolated(true); - auto throttle = factory.MaybeCreate(std::move(non_isolated_metadata)); - throttle->set_tick_clock_for_testing(&tick_clock); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(insecure_url, std::move(throttle)); - - tick_clock.Advance(expected_delay + kQueuingDelay); - scoped_environment_.FastForwardBy(expected_delay + kQueuingDelay); - } - histograms.ExpectUniqueSample( - kDelayHistogram, (expected_delay + kQueuingDelay).InMilliseconds(), 1); - histograms.ExpectUniqueSample(kQueuingDelayHistogram, - kQueuingDelay.InMilliseconds(), 1); - histograms.ExpectUniqueSample(kExpectedDelayHistogram, - expected_delay.InMilliseconds(), 1); - } -} - -// Make sure metrics are logged when the feature is enabled and disabled. -TEST_P(AdDelayThrottleEnabledParamTest, SecureMetrics) { - AdDelayThrottle::Factory factory; - const GURL insecure_url("http://example.test/ad.js"); - const GURL secure_url("https://example.test/ad.js"); - loader_factory_.AddResponse(insecure_url.spec(), "foo"); - loader_factory_.AddResponse(secure_url.spec(), "foo"); - - const char kSecureHistogram[] = "Ads.Features.ResourceIsSecure"; - { - base::HistogramTester histograms; - { - auto throttle = - factory.MaybeCreate(std::make_unique()); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(insecure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kSecureHistogram, - static_cast(AdDelayThrottle::SecureInfo::kInsecureAd), 1); - } - { - base::HistogramTester histograms; - { - auto throttle = - factory.MaybeCreate(std::make_unique()); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(secure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kSecureHistogram, - static_cast(AdDelayThrottle::SecureInfo::kSecureAd), 1); - } - { - base::HistogramTester histograms; - { - auto non_ad_metadata = std::make_unique(); - non_ad_metadata->set_is_ad_request(false); - client_ = std::make_unique(); - auto throttle = factory.MaybeCreate(std::move(non_ad_metadata)); - auto loader = CreateLoaderAndStart(insecure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kSecureHistogram, - static_cast(AdDelayThrottle::SecureInfo::kInsecureNonAd), 1); - } - { - base::HistogramTester histograms; - { - auto non_ad_metadata = std::make_unique(); - non_ad_metadata->set_is_ad_request(false); - auto throttle = factory.MaybeCreate(std::move(non_ad_metadata)); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(secure_url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kSecureHistogram, - static_cast(AdDelayThrottle::SecureInfo::kSecureNonAd), 1); - } -} - -TEST_P(AdDelayThrottleEnabledParamTest, IsolatedMetrics) { - AdDelayThrottle::Factory factory; - const GURL url("https://example.test/ad.js"); - loader_factory_.AddResponse(url.spec(), "foo"); - - const char kIsolatedHistogram[] = "Ads.Features.AdResourceIsIsolated"; - { - base::HistogramTester histograms; - { - auto throttle = - factory.MaybeCreate(std::make_unique()); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kIsolatedHistogram, - static_cast(AdDelayThrottle::IsolatedInfo::kIsolatedAd), 1); - } - { - base::HistogramTester histograms; - { - auto metadata = std::make_unique(); - metadata->set_is_non_isolated(true); - auto throttle = factory.MaybeCreate(std::move(metadata)); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectUniqueSample( - kIsolatedHistogram, - static_cast(AdDelayThrottle::IsolatedInfo::kNonIsolatedAd), 1); - } - { - base::HistogramTester histograms; - { - auto non_ad_metadata = std::make_unique(); - non_ad_metadata->set_is_ad_request(false); - client_ = std::make_unique(); - auto throttle = factory.MaybeCreate(std::move(non_ad_metadata)); - auto loader = CreateLoaderAndStart(url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectTotalCount(kIsolatedHistogram, 0); - } - { - base::HistogramTester histograms; - { - auto non_ad_metadata = std::make_unique(); - non_ad_metadata->set_is_ad_request(false); - non_ad_metadata->set_is_non_isolated(true); - auto throttle = factory.MaybeCreate(std::move(non_ad_metadata)); - client_ = std::make_unique(); - auto loader = CreateLoaderAndStart(url, std::move(throttle)); - scoped_environment_.FastForwardUntilNoTasksRemain(); - } - histograms.ExpectTotalCount(kIsolatedHistogram, 0); - } -} - -INSTANTIATE_TEST_SUITE_P(, - AdDelayThrottleEnabledParamTest, - ::testing::Values(true, false)); - -} // namespace subresource_filter diff --git a/components/subresource_filter/content/renderer/BUILD.gn b/components/subresource_filter/content/renderer/BUILD.gn index 131caba89fe6aa..64b6b08ae51408 100644 --- a/components/subresource_filter/content/renderer/BUILD.gn +++ b/components/subresource_filter/content/renderer/BUILD.gn @@ -4,8 +4,6 @@ static_library("renderer") { sources = [ - "ad_delay_renderer_metadata_provider.cc", - "ad_delay_renderer_metadata_provider.h", "ad_resource_tracker.cc", "ad_resource_tracker.h", "subresource_filter_agent.cc", diff --git a/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.cc b/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.cc deleted file mode 100644 index 11fab9d0c504d9..00000000000000 --- a/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h" - -#include "base/logging.h" -#include "content/public/renderer/render_frame.h" -#include "third_party/blink/public/platform/web_security_origin.h" -#include "third_party/blink/public/platform/web_url_request.h" -#include "third_party/blink/public/web/web_frame.h" -#include "third_party/blink/public/web/web_local_frame.h" - -namespace subresource_filter { - -AdDelayRendererMetadataProvider::AdDelayRendererMetadataProvider( - const blink::WebURLRequest& request, - content::URLLoaderThrottleProviderType type, - int render_frame_id) - : is_ad_request_(request.IsAdResource()), - is_non_isolated_(IsSubframeAndNonIsolated(type, render_frame_id)) {} - -AdDelayRendererMetadataProvider::~AdDelayRendererMetadataProvider() = default; - -// TODO(csharrison): Update |is_ad_request_| across redirects. -bool AdDelayRendererMetadataProvider::IsAdRequest() { - return is_ad_request_; -} - -bool AdDelayRendererMetadataProvider::RequestIsInNonIsolatedSubframe() { - return is_non_isolated_; -} - -// static -bool AdDelayRendererMetadataProvider::IsSubframeAndNonIsolated( - content::URLLoaderThrottleProviderType type, - int render_frame_id) { - // TODO(csharrison): Handle the worker case via threading information from the - // URLLoaderThrottleProvider's constructor. - if (type != content::URLLoaderThrottleProviderType::kFrame) - return false; - - auto* render_frame = content::RenderFrame::FromRoutingID(render_frame_id); - if (!render_frame || render_frame->IsMainFrame()) - return false; - - blink::WebFrame* web_frame = render_frame->GetWebFrame(); - - // The frame is non-isolated if it can access the top frame. - return web_frame->GetSecurityOrigin().CanAccess( - web_frame->Top()->GetSecurityOrigin()); -} - -} // namespace subresource_filter diff --git a/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h b/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h deleted file mode 100644 index 68fd33f232fc50..00000000000000 --- a/components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_ -#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_ - -#include "base/macros.h" -#include "components/subresource_filter/content/common/ad_delay_throttle.h" -#include "content/public/renderer/url_loader_throttle_provider.h" - -namespace blink { -class WebURLRequest; -} // namespace blink - -namespace subresource_filter { - -class AdDelayRendererMetadataProvider - : public AdDelayThrottle::MetadataProvider { - public: - explicit AdDelayRendererMetadataProvider( - const blink::WebURLRequest& request, - content::URLLoaderThrottleProviderType type, - int render_frame_id); - ~AdDelayRendererMetadataProvider() override; - - // AdDelayThrottle::MetadataProvider: - bool IsAdRequest() override; - bool RequestIsInNonIsolatedSubframe() override; - - private: - static bool IsSubframeAndNonIsolated( - content::URLLoaderThrottleProviderType type, - int render_frame_id); - - const bool is_ad_request_ = false; - const bool is_non_isolated_ = false; - - DISALLOW_COPY_AND_ASSIGN(AdDelayRendererMetadataProvider); -}; - -} // namespace subresource_filter - -#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_ diff --git a/components/subresource_filter/core/common/common_features.cc b/components/subresource_filter/core/common/common_features.cc index c859b031396a7b..9a3b1a69a8b138 100644 --- a/components/subresource_filter/core/common/common_features.cc +++ b/components/subresource_filter/core/common/common_features.cc @@ -8,9 +8,4 @@ namespace subresource_filter { const base::Feature kAdTagging{"AdTagging", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kDelayUnsafeAds{"DelayUnsafeAds", - base::FEATURE_DISABLED_BY_DEFAULT}; -const char kInsecureDelayParam[] = "insecure_delay"; -const char kNonIsolatedDelayParam[] = "non_isolated_delay"; - } // namespace subresource_filter