PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc

https://github.com/chromium/chromium
C++ | 1174 lines | 891 code | 170 blank | 113 comment | 12 complexity | d01194886a7183a53faa94e745e25f07 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
  5. #include <map>
  6. #include <memory>
  7. #include <tuple>
  8. #include <utility>
  9. #include "base/bind.h"
  10. #include "base/callback_helpers.h"
  11. #include "base/check.h"
  12. #include "base/command_line.h"
  13. #include "base/run_loop.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/test/metrics/histogram_tester.h"
  16. #include "base/test/scoped_feature_list.h"
  17. #include "base/test/test_simple_task_runner.h"
  18. #include "base/threading/thread_task_runner_handle.h"
  19. #include "base/time/time.h"
  20. #include "build/build_config.h"
  21. #include "components/content_settings/browser/page_specific_content_settings.h"
  22. #include "components/content_settings/core/common/content_settings_types.h"
  23. #include "components/infobars/content/content_infobar_manager.h"
  24. #include "components/infobars/core/confirm_infobar_delegate.h"
  25. #include "components/infobars/core/infobar.h"
  26. #include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
  27. #include "components/subresource_filter/content/browser/content_subresource_filter_web_contents_helper.h"
  28. #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h"
  29. #include "components/subresource_filter/content/browser/profile_interaction_manager.h"
  30. #include "components/subresource_filter/content/browser/subframe_navigation_test_utils.h"
  31. #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
  32. #include "components/subresource_filter/content/browser/throttle_manager_test_support.h"
  33. #include "components/subresource_filter/content/mojom/subresource_filter.mojom.h"
  34. #include "components/subresource_filter/core/browser/subresource_filter_features.h"
  35. #include "components/subresource_filter/core/common/common_features.h"
  36. #include "components/subresource_filter/core/common/test_ruleset_creator.h"
  37. #include "components/subresource_filter/core/common/test_ruleset_utils.h"
  38. #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
  39. #include "components/url_pattern_index/proto/rules.pb.h"
  40. #include "content/public/browser/navigation_handle.h"
  41. #include "content/public/browser/navigation_throttle.h"
  42. #include "content/public/browser/web_contents.h"
  43. #include "content/public/test/back_forward_cache_util.h"
  44. #include "content/public/test/mock_render_process_host.h"
  45. #include "content/public/test/navigation_simulator.h"
  46. #include "content/public/test/test_renderer_host.h"
  47. #include "content/public/test/test_utils.h"
  48. #include "mojo/public/cpp/bindings/associated_receiver.h"
  49. #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
  50. #include "net/base/net_errors.h"
  51. #include "testing/gtest/include/gtest/gtest.h"
  52. #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
  53. #include "third_party/blink/public/common/features.h"
  54. #include "url/url_constants.h"
  55. #if BUILDFLAG(IS_ANDROID)
  56. #include "components/messages/android/mock_message_dispatcher_bridge.h"
  57. #include "components/subresource_filter/content/browser/ads_blocked_message_delegate.h"
  58. #endif
  59. namespace subresource_filter {
  60. namespace proto = url_pattern_index::proto;
  61. const char kTestURLWithActivation[] = "https://www.page-with-activation.com/";
  62. const char kTestURLWithActivation2[] =
  63. "https://www.page-with-activation-2.com/";
  64. const char kTestURLWithDryRun[] = "https://www.page-with-dryrun.com/";
  65. const char kTestURLWithNoActivation[] =
  66. "https://www.page-without-activation.com/";
  67. const char kReadyToCommitResultsInCommitHistogram[] =
  68. "SubresourceFilter.Experimental.ReadyToCommitResultsInCommit2";
  69. const char kReadyToCommitResultsInCommitRestrictedAdFrameNavigationHistogram[] =
  70. "SubresourceFilter.Experimental.ReadyToCommitResultsInCommit2."
  71. "RestrictedAdFrameNavigation";
  72. // Enum determining when the mock page state throttle notifies the throttle
  73. // manager of page level activation state.
  74. enum PageActivationNotificationTiming {
  75. WILL_START_REQUEST,
  76. WILL_PROCESS_RESPONSE,
  77. };
  78. class FakeSubresourceFilterAgent : public mojom::SubresourceFilterAgent {
  79. public:
  80. FakeSubresourceFilterAgent() = default;
  81. ~FakeSubresourceFilterAgent() override = default;
  82. void OnSubresourceFilterAgentReceiver(
  83. mojo::ScopedInterfaceEndpointHandle handle) {
  84. receiver_.reset();
  85. receiver_.Bind(
  86. mojo::PendingAssociatedReceiver<mojom::SubresourceFilterAgent>(
  87. std::move(handle)));
  88. }
  89. // mojom::SubresourceFilterAgent:
  90. void ActivateForNextCommittedLoad(
  91. mojom::ActivationStatePtr activation_state,
  92. const absl::optional<blink::FrameAdEvidence>& ad_evidence) override {
  93. last_activation_ = std::move(activation_state);
  94. is_ad_subframe_ =
  95. ad_evidence.has_value() && ad_evidence->IndicatesAdSubframe();
  96. }
  97. // These methods reset state back to default when they are called.
  98. bool LastAdSubframe() {
  99. bool is_ad_subframe = is_ad_subframe_;
  100. is_ad_subframe_ = false;
  101. return is_ad_subframe;
  102. }
  103. absl::optional<bool> LastActivated() {
  104. if (!last_activation_)
  105. return absl::nullopt;
  106. bool activated =
  107. last_activation_->activation_level != mojom::ActivationLevel::kDisabled;
  108. last_activation_.reset();
  109. return activated;
  110. }
  111. private:
  112. mojom::ActivationStatePtr last_activation_;
  113. bool is_ad_subframe_ = false;
  114. mojo::AssociatedReceiver<mojom::SubresourceFilterAgent> receiver_{this};
  115. };
  116. // Simple throttle that sends page-level activation to the manager for a
  117. // specific set of URLs.
  118. class MockPageStateActivationThrottle : public content::NavigationThrottle {
  119. public:
  120. MockPageStateActivationThrottle(
  121. content::NavigationHandle* navigation_handle,
  122. PageActivationNotificationTiming activation_throttle_state)
  123. : content::NavigationThrottle(navigation_handle),
  124. activation_throttle_state_(activation_throttle_state) {
  125. // Add some default activations.
  126. mojom::ActivationState enabled_state;
  127. enabled_state.activation_level = mojom::ActivationLevel::kEnabled;
  128. mojom::ActivationState dry_run_state;
  129. dry_run_state.activation_level = mojom::ActivationLevel::kDryRun;
  130. mock_page_activations_[GURL(kTestURLWithActivation)] = enabled_state;
  131. mock_page_activations_[GURL(kTestURLWithActivation2)] = enabled_state;
  132. mock_page_activations_[GURL(kTestURLWithDryRun)] = dry_run_state;
  133. mock_page_activations_[GURL(kTestURLWithNoActivation)] =
  134. mojom::ActivationState();
  135. }
  136. MockPageStateActivationThrottle(const MockPageStateActivationThrottle&) =
  137. delete;
  138. MockPageStateActivationThrottle& operator=(
  139. const MockPageStateActivationThrottle&) = delete;
  140. ~MockPageStateActivationThrottle() override {}
  141. // content::NavigationThrottle:
  142. content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
  143. return MaybeNotifyActivation(WILL_START_REQUEST);
  144. }
  145. content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
  146. override {
  147. return MaybeNotifyActivation(WILL_PROCESS_RESPONSE);
  148. }
  149. const char* GetNameForLogging() override {
  150. return "MockPageStateActivationThrottle";
  151. }
  152. private:
  153. content::NavigationThrottle::ThrottleCheckResult MaybeNotifyActivation(
  154. PageActivationNotificationTiming throttle_state) {
  155. if (throttle_state == activation_throttle_state_) {
  156. auto it = mock_page_activations_.find(navigation_handle()->GetURL());
  157. if (it != mock_page_activations_.end()) {
  158. // The throttle manager does not use the activation decision.
  159. SubresourceFilterObserverManager::FromWebContents(
  160. navigation_handle()->GetWebContents())
  161. ->NotifyPageActivationComputed(navigation_handle(), it->second);
  162. }
  163. }
  164. return content::NavigationThrottle::PROCEED;
  165. }
  166. std::map<GURL, mojom::ActivationState> mock_page_activations_;
  167. PageActivationNotificationTiming activation_throttle_state_;
  168. };
  169. class ContentSubresourceFilterThrottleManagerTest
  170. : public content::RenderViewHostTestHarness,
  171. public content::WebContentsObserver,
  172. public ::testing::WithParamInterface<PageActivationNotificationTiming> {
  173. public:
  174. ContentSubresourceFilterThrottleManagerTest() {}
  175. ContentSubresourceFilterThrottleManagerTest(
  176. const ContentSubresourceFilterThrottleManagerTest&) = delete;
  177. ContentSubresourceFilterThrottleManagerTest& operator=(
  178. const ContentSubresourceFilterThrottleManagerTest&) = delete;
  179. ~ContentSubresourceFilterThrottleManagerTest() override {}
  180. // content::RenderViewHostTestHarness:
  181. void SetUp() override {
  182. content::RenderViewHostTestHarness::SetUp();
  183. content::WebContents* web_contents =
  184. RenderViewHostTestHarness::web_contents();
  185. CreateAgentForHost(web_contents->GetPrimaryMainFrame());
  186. // Initialize the ruleset dealer. Allowlisted URLs must also match a
  187. // disallowed rule in order to work correctly.
  188. std::vector<proto::UrlRule> rules;
  189. rules.push_back(testing::CreateAllowlistRuleForDocument(
  190. "allowlist.com", proto::ACTIVATION_TYPE_DOCUMENT,
  191. {"page-with-activation.com"}));
  192. rules.push_back(testing::CreateRuleForDocument(
  193. "allowlist.com", proto::ACTIVATION_TYPE_DOCUMENT,
  194. {"page-with-activation.com"}));
  195. rules.push_back(testing::CreateAllowlistSuffixRule("not_disallowed.html"));
  196. rules.push_back(testing::CreateSuffixRule("disallowed.html"));
  197. ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
  198. rules, &test_ruleset_pair_));
  199. // Make the blocking task runner run on the current task runner for the
  200. // tests, to ensure that the NavigationSimulator properly runs all necessary
  201. // tasks while waiting for throttle checks to finish.
  202. dealer_handle_ = std::make_unique<VerifiedRulesetDealer::Handle>(
  203. base::ThreadTaskRunnerHandle::Get());
  204. dealer_handle_->TryOpenAndSetRulesetFile(test_ruleset_pair_.indexed.path,
  205. /*expected_checksum=*/0,
  206. base::DoNothing());
  207. throttle_manager_test_support_ =
  208. std::make_unique<ThrottleManagerTestSupport>(web_contents);
  209. // Turn off smart UI to make it easier to reason about expectations on
  210. // ShowNotification() being invoked.
  211. throttle_manager_test_support_->SetShouldUseSmartUI(false);
  212. ContentSubresourceFilterWebContentsHelper::CreateForWebContents(
  213. web_contents, throttle_manager_test_support_->profile_context(),
  214. /*database_manager=*/nullptr, dealer_handle_.get());
  215. Observe(web_contents);
  216. NavigateAndCommit(GURL("https://example.first"));
  217. #if BUILDFLAG(IS_ANDROID)
  218. message_dispatcher_bridge_.SetMessagesEnabledForEmbedder(true);
  219. messages::MessageDispatcherBridge::SetInstanceForTesting(
  220. &message_dispatcher_bridge_);
  221. #endif
  222. }
  223. void TearDown() override {
  224. throttle_manager_test_support_.reset();
  225. dealer_handle_.reset();
  226. base::RunLoop().RunUntilIdle();
  227. content::RenderViewHostTestHarness::TearDown();
  228. #if BUILDFLAG(IS_ANDROID)
  229. messages::MessageDispatcherBridge::SetInstanceForTesting(nullptr);
  230. #endif
  231. }
  232. void ExpectActivationSignalForFrame(
  233. content::RenderFrameHost* rfh,
  234. bool expect_activation,
  235. bool expect_is_ad_subframe = false,
  236. bool expect_activation_sent_to_agent = true) {
  237. // In some cases we need to verify that messages were _not_ sent, in which
  238. // case using a Wait() idiom would cause hangs. RunUntilIdle instead to
  239. // ensure mojo calls make it to the fake agent.
  240. base::RunLoop().RunUntilIdle();
  241. FakeSubresourceFilterAgent* agent = agent_map_[rfh].get();
  242. absl::optional<bool> last_activated = agent->LastActivated();
  243. EXPECT_EQ(expect_activation, last_activated && *last_activated);
  244. EXPECT_EQ(expect_is_ad_subframe, agent->LastAdSubframe());
  245. EXPECT_EQ(expect_activation_sent_to_agent, last_activated.has_value());
  246. }
  247. // Helper methods:
  248. void CreateTestNavigation(const GURL& url,
  249. content::RenderFrameHost* render_frame_host) {
  250. DCHECK(render_frame_host);
  251. navigation_simulator_ =
  252. content::NavigationSimulator::CreateRendererInitiated(
  253. url, render_frame_host);
  254. }
  255. content::NavigationSimulator* navigation_simulator() {
  256. return navigation_simulator_.get();
  257. }
  258. content::RenderFrameHost* CreateSubframeWithTestNavigation(
  259. const GURL& url,
  260. content::RenderFrameHost* parent) {
  261. content::RenderFrameHost* subframe =
  262. content::RenderFrameHostTester::For(parent)->AppendChild(
  263. base::StringPrintf("subframe-%s", url.spec().c_str()));
  264. CreateTestNavigation(url, subframe);
  265. return subframe;
  266. }
  267. content::RenderFrameHost* CreateFencedFrameWithTestNavigation(
  268. const GURL& url,
  269. content::RenderFrameHost* parent) {
  270. content::RenderFrameHost* fenced_frame =
  271. content::RenderFrameHostTester::For(parent)->AppendFencedFrame();
  272. CreateTestNavigation(url, fenced_frame);
  273. return fenced_frame;
  274. }
  275. void NavigateAndCommitMainFrame(const GURL& url) {
  276. CreateTestNavigation(url, main_rfh());
  277. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  278. SimulateStartAndGetResult(navigation_simulator()));
  279. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  280. SimulateCommitAndGetResult(navigation_simulator()));
  281. }
  282. bool ManagerHasRulesetHandle() {
  283. return throttle_manager()->ruleset_handle_for_testing();
  284. }
  285. #if BUILDFLAG(IS_ANDROID)
  286. void SimulateMessageDismissal() {
  287. throttle_manager()
  288. ->profile_interaction_manager_for_testing()
  289. ->ads_blocked_message_delegate_for_testing()
  290. ->DismissMessageForTesting(messages::DismissReason::SCOPE_DESTROYED);
  291. }
  292. #endif
  293. bool ads_blocked_in_content_settings() {
  294. auto* content_settings =
  295. content_settings::PageSpecificContentSettings::GetForFrame(
  296. content::RenderViewHostTestHarness::web_contents()
  297. ->GetPrimaryMainFrame());
  298. return content_settings->IsContentBlocked(ContentSettingsType::ADS);
  299. }
  300. protected:
  301. // content::WebContentsObserver
  302. void RenderFrameCreated(content::RenderFrameHost* new_host) override {
  303. CreateAgentForHost(new_host);
  304. }
  305. void RenderFrameDeleted(content::RenderFrameHost* host) override {
  306. agent_map_.erase(host);
  307. }
  308. void DidStartNavigation(
  309. content::NavigationHandle* navigation_handle) override {
  310. if (navigation_handle->IsSameDocument())
  311. return;
  312. // Inject the proper throttles at this time.
  313. std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
  314. PageActivationNotificationTiming state =
  315. ::testing::UnitTest::GetInstance()->current_test_info()->value_param()
  316. ? GetParam()
  317. : WILL_PROCESS_RESPONSE;
  318. throttles.push_back(std::make_unique<MockPageStateActivationThrottle>(
  319. navigation_handle, state));
  320. ContentSubresourceFilterThrottleManager::FromNavigationHandle(
  321. *navigation_handle)
  322. ->MaybeAppendNavigationThrottles(navigation_handle, &throttles);
  323. created_safe_browsing_throttle_for_last_navigation_ = false;
  324. for (auto& it : throttles) {
  325. if (strcmp(it->GetNameForLogging(),
  326. "SubresourceFilterSafeBrowsingActivationThrottle") == 0) {
  327. created_safe_browsing_throttle_for_last_navigation_ = true;
  328. }
  329. navigation_handle->RegisterThrottleForTesting(std::move(it));
  330. }
  331. }
  332. void CreateAgentForHost(content::RenderFrameHost* host) {
  333. auto new_agent = std::make_unique<FakeSubresourceFilterAgent>();
  334. host->GetRemoteAssociatedInterfaces()->OverrideBinderForTesting(
  335. mojom::SubresourceFilterAgent::Name_,
  336. base::BindRepeating(
  337. &FakeSubresourceFilterAgent::OnSubresourceFilterAgentReceiver,
  338. base::Unretained(new_agent.get())));
  339. agent_map_[host] = std::move(new_agent);
  340. }
  341. ContentSubresourceFilterThrottleManager* throttle_manager() {
  342. return ContentSubresourceFilterThrottleManager::FromPage(
  343. RenderViewHostTestHarness::web_contents()->GetPrimaryPage());
  344. }
  345. bool created_safe_browsing_throttle_for_current_navigation() const {
  346. return created_safe_browsing_throttle_for_last_navigation_;
  347. }
  348. void CreateSafeBrowsingDatabaseManager() {
  349. scoped_refptr<FakeSafeBrowsingDatabaseManager> database_manager =
  350. base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>();
  351. web_contents_helper()->SetDatabaseManagerForTesting(
  352. std::move(database_manager));
  353. }
  354. VerifiedRulesetDealer::Handle* dealer_handle() {
  355. return dealer_handle_.get();
  356. }
  357. #if BUILDFLAG(IS_ANDROID)
  358. messages::MockMessageDispatcherBridge message_dispatcher_bridge_;
  359. #endif
  360. private:
  361. ContentSubresourceFilterWebContentsHelper* web_contents_helper() {
  362. return ContentSubresourceFilterWebContentsHelper::FromWebContents(
  363. RenderViewHostTestHarness::web_contents());
  364. }
  365. testing::TestRulesetCreator test_ruleset_creator_;
  366. testing::TestRulesetPair test_ruleset_pair_;
  367. std::unique_ptr<ThrottleManagerTestSupport> throttle_manager_test_support_;
  368. std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_;
  369. std::map<content::RenderFrameHost*,
  370. std::unique_ptr<FakeSubresourceFilterAgent>>
  371. agent_map_;
  372. std::unique_ptr<content::NavigationSimulator> navigation_simulator_;
  373. bool created_safe_browsing_throttle_for_last_navigation_ = false;
  374. };
  375. INSTANTIATE_TEST_SUITE_P(All,
  376. ContentSubresourceFilterThrottleManagerTest,
  377. ::testing::Values(WILL_START_REQUEST,
  378. WILL_PROCESS_RESPONSE));
  379. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  380. ActivateMainFrameAndFilterSubframeNavigation) {
  381. // Commit a navigation that triggers page level activation.
  382. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  383. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  384. // A disallowed subframe navigation should be successfully filtered.
  385. #if BUILDFLAG(IS_ANDROID)
  386. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  387. #endif
  388. CreateSubframeWithTestNavigation(
  389. GURL("https://www.example.com/disallowed.html"), main_rfh());
  390. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  391. SimulateStartAndGetResult(navigation_simulator()));
  392. EXPECT_TRUE(ads_blocked_in_content_settings());
  393. #if BUILDFLAG(IS_ANDROID)
  394. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  395. #endif
  396. }
  397. #if BUILDFLAG(IS_ANDROID)
  398. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  399. NoCrashWhenMessageDelegateIsNotPresent) {
  400. auto* web_contents = RenderViewHostTestHarness::web_contents();
  401. web_contents->RemoveUserData(
  402. subresource_filter::AdsBlockedMessageDelegate::UserDataKey());
  403. // Commit a navigation that triggers page level activation.
  404. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  405. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  406. // A disallowed subframe navigation should be successfully filtered, and the
  407. // lack of infobar manager should not cause a crash.
  408. CreateSubframeWithTestNavigation(
  409. GURL("https://www.example.com/disallowed.html"), main_rfh());
  410. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  411. SimulateStartAndGetResult(navigation_simulator()));
  412. EXPECT_TRUE(ads_blocked_in_content_settings());
  413. }
  414. #endif
  415. TEST_P(ContentSubresourceFilterThrottleManagerTest, NoPageActivation) {
  416. // This test assumes that we're not in DryRun mode.
  417. base::test::ScopedFeatureList scoped_feature;
  418. scoped_feature.InitAndDisableFeature(kAdTagging);
  419. // Commit a navigation that triggers page level activation.
  420. NavigateAndCommitMainFrame(GURL(kTestURLWithNoActivation));
  421. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
  422. EXPECT_FALSE(ManagerHasRulesetHandle());
  423. // A disallowed subframe navigation should not be filtered.
  424. #if BUILDFLAG(IS_ANDROID)
  425. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  426. #endif
  427. CreateSubframeWithTestNavigation(
  428. GURL("https://www.example.com/disallowed.html"), main_rfh());
  429. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  430. SimulateCommitAndGetResult(navigation_simulator()));
  431. EXPECT_FALSE(ads_blocked_in_content_settings());
  432. #if BUILDFLAG(IS_ANDROID)
  433. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  434. #endif
  435. }
  436. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  437. ActivateMainFrameAndDoNotFilterDryRun) {
  438. // Commit a navigation that triggers page level activation.
  439. NavigateAndCommitMainFrame(GURL(kTestURLWithDryRun));
  440. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  441. // A disallowed subframe navigation should not be filtered in dry-run mode.
  442. #if BUILDFLAG(IS_ANDROID)
  443. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  444. #endif
  445. CreateSubframeWithTestNavigation(
  446. GURL("https://www.example.com/disallowed.html"), main_rfh());
  447. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  448. SimulateStartAndGetResult(navigation_simulator()));
  449. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  450. SimulateCommitAndGetResult(navigation_simulator()));
  451. content::RenderFrameHost* child =
  452. navigation_simulator()->GetFinalRenderFrameHost();
  453. // But it should still be activated.
  454. ExpectActivationSignalForFrame(child, true /* expect_activation */,
  455. true /* is_ad_subframe */);
  456. EXPECT_FALSE(ads_blocked_in_content_settings());
  457. #if BUILDFLAG(IS_ANDROID)
  458. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  459. #endif
  460. }
  461. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  462. ActivateMainFrameAndFilterSubframeNavigationOnRedirect) {
  463. // Commit a navigation that triggers page level activation.
  464. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  465. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  466. // A disallowed subframe navigation via redirect should be successfully
  467. // filtered.
  468. #if BUILDFLAG(IS_ANDROID)
  469. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  470. #endif
  471. CreateSubframeWithTestNavigation(
  472. GURL("https://www.example.com/before-redirect.html"), main_rfh());
  473. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  474. SimulateStartAndGetResult(navigation_simulator()));
  475. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  476. SimulateRedirectAndGetResult(
  477. navigation_simulator(),
  478. GURL("https://www.example.com/disallowed.html")));
  479. EXPECT_TRUE(ads_blocked_in_content_settings());
  480. #if BUILDFLAG(IS_ANDROID)
  481. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  482. #endif
  483. }
  484. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  485. ActivateMainFrameAndDoNotFilterSubframeNavigation) {
  486. // Commit a navigation that triggers page level activation.
  487. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  488. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  489. // An allowed subframe navigation should complete successfully.
  490. #if BUILDFLAG(IS_ANDROID)
  491. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  492. #endif
  493. CreateSubframeWithTestNavigation(
  494. GURL("https://www.example.com/allowed1.html"), main_rfh());
  495. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  496. SimulateStartAndGetResult(navigation_simulator()));
  497. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  498. SimulateRedirectAndGetResult(
  499. navigation_simulator(),
  500. GURL("https://www.example.com/allowed2.html")));
  501. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  502. SimulateCommitAndGetResult(navigation_simulator()));
  503. content::RenderFrameHost* child =
  504. navigation_simulator()->GetFinalRenderFrameHost();
  505. ExpectActivationSignalForFrame(child, true /* expect_activation */);
  506. EXPECT_FALSE(ads_blocked_in_content_settings());
  507. #if BUILDFLAG(IS_ANDROID)
  508. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  509. #endif
  510. }
  511. // This should fail if the throttle manager notifies the delegate twice of a
  512. // disallowed load for the same page load.
  513. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  514. ActivateMainFrameAndFilterTwoSubframeNavigations) {
  515. // Commit a navigation that triggers page level activation.
  516. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  517. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  518. // A disallowed subframe navigation should be successfully filtered.
  519. #if BUILDFLAG(IS_ANDROID)
  520. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  521. #endif
  522. CreateSubframeWithTestNavigation(
  523. GURL("https://www.example.com/1/disallowed.html"), main_rfh());
  524. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  525. SimulateStartAndGetResult(navigation_simulator()));
  526. EXPECT_TRUE(ads_blocked_in_content_settings());
  527. CreateSubframeWithTestNavigation(
  528. GURL("https://www.example.com/2/disallowed.html"), main_rfh());
  529. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  530. SimulateStartAndGetResult(navigation_simulator()));
  531. EXPECT_TRUE(ads_blocked_in_content_settings());
  532. #if BUILDFLAG(IS_ANDROID)
  533. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  534. #endif
  535. }
  536. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  537. ActivateTwoMainFramesAndFilterTwoSubframeNavigations) {
  538. // Commit a navigation that triggers page level activation.
  539. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  540. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  541. // A disallowed subframe navigation should be successfully filtered.
  542. #if BUILDFLAG(IS_ANDROID)
  543. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  544. #endif
  545. CreateSubframeWithTestNavigation(
  546. GURL("https://www.example.com/1/disallowed.html"), main_rfh());
  547. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  548. SimulateStartAndGetResult(navigation_simulator()));
  549. EXPECT_TRUE(ads_blocked_in_content_settings());
  550. #if BUILDFLAG(IS_ANDROID)
  551. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  552. #endif
  553. // Commit another navigation that triggers page level activation.
  554. #if BUILDFLAG(IS_ANDROID)
  555. // Since the MessageDispatcherBridge is mocked, navigation events are not
  556. // tracked by the messages system to automatically dismiss the message on
  557. // navigation. The message dismissal is therefore simulated.
  558. SimulateMessageDismissal();
  559. #endif
  560. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation2));
  561. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  562. EXPECT_FALSE(ads_blocked_in_content_settings());
  563. #if BUILDFLAG(IS_ANDROID)
  564. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  565. #endif
  566. CreateSubframeWithTestNavigation(
  567. GURL("https://www.example.com/2/disallowed.html"), main_rfh());
  568. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  569. SimulateStartAndGetResult(navigation_simulator()));
  570. EXPECT_TRUE(ads_blocked_in_content_settings());
  571. #if BUILDFLAG(IS_ANDROID)
  572. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  573. #endif
  574. }
  575. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  576. DoNotFilterForInactiveFrame) {
  577. // This test assumes that we're not in DryRun mode.
  578. base::test::ScopedFeatureList scoped_feature;
  579. scoped_feature.InitAndDisableFeature(kAdTagging);
  580. NavigateAndCommitMainFrame(GURL("https://do-not-activate.html"));
  581. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
  582. // A subframe navigation should complete successfully.
  583. #if BUILDFLAG(IS_ANDROID)
  584. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  585. #endif
  586. CreateSubframeWithTestNavigation(GURL("https://www.example.com/allowed.html"),
  587. main_rfh());
  588. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  589. SimulateStartAndGetResult(navigation_simulator()));
  590. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  591. SimulateCommitAndGetResult(navigation_simulator()));
  592. content::RenderFrameHost* child =
  593. navigation_simulator()->GetFinalRenderFrameHost();
  594. ExpectActivationSignalForFrame(child, false /* expect_activation */);
  595. EXPECT_FALSE(ads_blocked_in_content_settings());
  596. #if BUILDFLAG(IS_ANDROID)
  597. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  598. #endif
  599. }
  600. // Once there are no activated frames, the manager drops its ruleset handle. If
  601. // another frame is activated, make sure the handle is regenerated.
  602. TEST_P(ContentSubresourceFilterThrottleManagerTest, RulesetHandleRegeneration) {
  603. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  604. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  605. #if BUILDFLAG(IS_ANDROID)
  606. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  607. #endif
  608. CreateSubframeWithTestNavigation(
  609. GURL("https://www.example.com/disallowed.html"), main_rfh());
  610. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  611. SimulateStartAndGetResult(navigation_simulator()));
  612. EXPECT_TRUE(ads_blocked_in_content_settings());
  613. #if BUILDFLAG(IS_ANDROID)
  614. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  615. #endif
  616. // Simulate a renderer crash which should delete the frame.
  617. EXPECT_TRUE(ManagerHasRulesetHandle());
  618. process()->SimulateCrash();
  619. EXPECT_FALSE(ManagerHasRulesetHandle());
  620. #if BUILDFLAG(IS_ANDROID)
  621. // Since the MessageDispatcherBridge is mocked, navigation events are not
  622. // tracked by the messages system to automatically dismiss the message on
  623. // navigation. The message dismissal is therefore simulated.
  624. SimulateMessageDismissal();
  625. #endif
  626. NavigateAndCommit(GURL("https://example.reset"));
  627. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  628. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  629. EXPECT_FALSE(ads_blocked_in_content_settings());
  630. #if BUILDFLAG(IS_ANDROID)
  631. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  632. #endif
  633. CreateSubframeWithTestNavigation(
  634. GURL("https://www.example.com/disallowed.html"), main_rfh());
  635. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  636. SimulateStartAndGetResult(navigation_simulator()));
  637. EXPECT_TRUE(ads_blocked_in_content_settings());
  638. #if BUILDFLAG(IS_ANDROID)
  639. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  640. #endif
  641. }
  642. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  643. SameSiteNavigation_RulesetGoesAway) {
  644. // The test assumes the previous page gets deleted after navigation and
  645. // ManagerHasRulesetHandle() will return false. Disable back/forward cache to
  646. // ensure that it doesn't get preserved in the cache.
  647. DisableBackForwardCacheForTesting(
  648. RenderViewHostTestHarness::web_contents(),
  649. content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
  650. // This test assumes that we're not in DryRun mode.
  651. base::test::ScopedFeatureList scoped_feature;
  652. scoped_feature.InitAndDisableFeature(kAdTagging);
  653. GURL same_site_inactive_url =
  654. GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
  655. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  656. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  657. EXPECT_TRUE(ManagerHasRulesetHandle());
  658. NavigateAndCommitMainFrame(same_site_inactive_url);
  659. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
  660. EXPECT_FALSE(ManagerHasRulesetHandle());
  661. // A subframe navigation should complete successfully.
  662. #if BUILDFLAG(IS_ANDROID)
  663. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  664. #endif
  665. CreateSubframeWithTestNavigation(
  666. GURL("https://www.example.com/disallowed.html"), main_rfh());
  667. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  668. SimulateStartAndGetResult(navigation_simulator()));
  669. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  670. SimulateCommitAndGetResult(navigation_simulator()));
  671. content::RenderFrameHost* child =
  672. navigation_simulator()->GetFinalRenderFrameHost();
  673. ExpectActivationSignalForFrame(child, false /* expect_activation */);
  674. EXPECT_FALSE(ads_blocked_in_content_settings());
  675. #if BUILDFLAG(IS_ANDROID)
  676. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  677. #endif
  678. }
  679. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  680. SameSiteFailedNavigation_MaintainActivation) {
  681. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  682. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  683. EXPECT_TRUE(ManagerHasRulesetHandle());
  684. GURL same_site_inactive_url =
  685. GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
  686. CreateTestNavigation(same_site_inactive_url, main_rfh());
  687. SimulateFailedNavigation(navigation_simulator(), net::ERR_ABORTED);
  688. EXPECT_TRUE(ManagerHasRulesetHandle());
  689. // The aborted navigation does not pass through ReadyToCommitNavigation so no
  690. // ActivateForNextCommittedLoad mojo call is expected.
  691. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */,
  692. false /* expect_is_ad_subframe */,
  693. false /* expect_activation_sent_to_agent */);
  694. // A subframe navigation fail.
  695. #if BUILDFLAG(IS_ANDROID)
  696. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  697. #endif
  698. CreateSubframeWithTestNavigation(
  699. GURL("https://www.example.com/disallowed.html"), main_rfh());
  700. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  701. SimulateStartAndGetResult(navigation_simulator()));
  702. EXPECT_TRUE(ads_blocked_in_content_settings());
  703. #if BUILDFLAG(IS_ANDROID)
  704. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  705. #endif
  706. }
  707. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  708. FailedNavigationToErrorPage_NoActivation) {
  709. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  710. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  711. EXPECT_TRUE(ManagerHasRulesetHandle());
  712. GURL same_site_inactive_url =
  713. GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
  714. CreateTestNavigation(same_site_inactive_url, main_rfh());
  715. SimulateFailedNavigation(navigation_simulator(), net::ERR_FAILED);
  716. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
  717. #if BUILDFLAG(IS_ANDROID)
  718. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  719. #endif
  720. CreateSubframeWithTestNavigation(
  721. GURL("https://www.example.com/disallowed.html"), main_rfh());
  722. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  723. SimulateStartAndGetResult(navigation_simulator()));
  724. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  725. SimulateCommitAndGetResult(navigation_simulator()));
  726. content::RenderFrameHost* child =
  727. navigation_simulator()->GetFinalRenderFrameHost();
  728. ExpectActivationSignalForFrame(child, false /* expect_activation */);
  729. EXPECT_FALSE(ads_blocked_in_content_settings());
  730. #if BUILDFLAG(IS_ANDROID)
  731. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  732. #endif
  733. }
  734. // Ensure activation propagates into great-grandchild frames, including cross
  735. // process ones.
  736. TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation) {
  737. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  738. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  739. // Navigate a subframe to a URL that is not itself disallowed. Subresource
  740. // filtering for this subframe document should still be activated.
  741. CreateSubframeWithTestNavigation(GURL("https://www.a.com/allowed.html"),
  742. main_rfh());
  743. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  744. SimulateStartAndGetResult(navigation_simulator()));
  745. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  746. SimulateCommitAndGetResult(navigation_simulator()));
  747. content::RenderFrameHost* subframe1 =
  748. navigation_simulator()->GetFinalRenderFrameHost();
  749. ExpectActivationSignalForFrame(subframe1, true /* expect_activation */);
  750. // Navigate a sub-subframe to a URL that is not itself disallowed. Subresource
  751. // filtering for this subframe document should still be activated.
  752. CreateSubframeWithTestNavigation(GURL("https://www.b.com/allowed.html"),
  753. subframe1);
  754. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  755. SimulateStartAndGetResult(navigation_simulator()));
  756. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  757. SimulateCommitAndGetResult(navigation_simulator()));
  758. content::RenderFrameHost* subframe2 =
  759. navigation_simulator()->GetFinalRenderFrameHost();
  760. ExpectActivationSignalForFrame(subframe2, true /* expect_activation */);
  761. // A final, nested subframe navigation is filtered.
  762. #if BUILDFLAG(IS_ANDROID)
  763. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  764. #endif
  765. CreateSubframeWithTestNavigation(GURL("https://www.c.com/disallowed.html"),
  766. subframe2);
  767. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  768. SimulateStartAndGetResult(navigation_simulator()));
  769. EXPECT_TRUE(ads_blocked_in_content_settings());
  770. #if BUILDFLAG(IS_ANDROID)
  771. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  772. #endif
  773. }
  774. // Ensure activation propagates through allowlisted documents.
  775. // crbug.com/1010000: crashes on win
  776. #if BUILDFLAG(IS_WIN)
  777. #define MAYBE_ActivationPropagation2 DISABLED_ActivationPropagation2
  778. #else
  779. #define MAYBE_ActivationPropagation2 ActivationPropagation2
  780. #endif
  781. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  782. MAYBE_ActivationPropagation2) {
  783. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  784. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  785. // Navigate a subframe that is not filtered, but should still activate.
  786. CreateSubframeWithTestNavigation(GURL("https://allowlist.com"), main_rfh());
  787. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  788. SimulateStartAndGetResult(navigation_simulator()));
  789. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  790. SimulateCommitAndGetResult(navigation_simulator()));
  791. content::RenderFrameHost* subframe1 =
  792. navigation_simulator()->GetFinalRenderFrameHost();
  793. ExpectActivationSignalForFrame(subframe1, true /* expect_activation */);
  794. // Navigate a sub-subframe that is not filtered due to the allowlist.
  795. #if BUILDFLAG(IS_ANDROID)
  796. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  797. #endif
  798. CreateSubframeWithTestNavigation(
  799. GURL("https://www.example.com/disallowed.html"), subframe1);
  800. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  801. SimulateStartAndGetResult(navigation_simulator()));
  802. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  803. SimulateCommitAndGetResult(navigation_simulator()));
  804. content::RenderFrameHost* subframe2 =
  805. navigation_simulator()->GetFinalRenderFrameHost();
  806. ExpectActivationSignalForFrame(subframe2, true /* expect_activation */);
  807. EXPECT_FALSE(ads_blocked_in_content_settings());
  808. #if BUILDFLAG(IS_ANDROID)
  809. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  810. #endif
  811. // An identical series of events that don't match allowlist rules cause
  812. // filtering.
  813. CreateSubframeWithTestNavigation(GURL("https://average-joe.com"), main_rfh());
  814. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  815. SimulateStartAndGetResult(navigation_simulator()));
  816. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  817. SimulateCommitAndGetResult(navigation_simulator()));
  818. content::RenderFrameHost* subframe3 =
  819. navigation_simulator()->GetFinalRenderFrameHost();
  820. ExpectActivationSignalForFrame(subframe3, true /* expect_activation */);
  821. // Navigate a sub-subframe that is not filtered due to the allowlist.
  822. #if BUILDFLAG(IS_ANDROID)
  823. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  824. #endif
  825. CreateSubframeWithTestNavigation(
  826. GURL("https://www.example.com/disallowed.html"), subframe3);
  827. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  828. SimulateStartAndGetResult(navigation_simulator()));
  829. EXPECT_TRUE(ads_blocked_in_content_settings());
  830. #if BUILDFLAG(IS_ANDROID)
  831. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  832. #endif
  833. }
  834. // Same-site navigations within a single RFH do not persist activation.
  835. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  836. SameSiteNavigationStopsActivation) {
  837. // This test assumes that we're not in DryRun mode.
  838. base::test::ScopedFeatureList scoped_feature;
  839. scoped_feature.InitAndDisableFeature(kAdTagging);
  840. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  841. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
  842. // Mock a same-site navigation, in the same RFH, this URL does not trigger
  843. // page level activation.
  844. NavigateAndCommitMainFrame(
  845. GURL(base::StringPrintf("%s/some_path/", kTestURLWithActivation)));
  846. ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
  847. #if BUILDFLAG(IS_ANDROID)
  848. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
  849. #endif
  850. CreateSubframeWithTestNavigation(
  851. GURL("https://www.example.com/disallowed.html"), main_rfh());
  852. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  853. SimulateStartAndGetResult(navigation_simulator()));
  854. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  855. SimulateCommitAndGetResult(navigation_simulator()));
  856. content::RenderFrameHost* child =
  857. navigation_simulator()->GetFinalRenderFrameHost();
  858. ExpectActivationSignalForFrame(child, false /* expect_activation */);
  859. EXPECT_FALSE(ads_blocked_in_content_settings());
  860. #if BUILDFLAG(IS_ANDROID)
  861. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  862. #endif
  863. }
  864. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  865. CreateHelperForWebContents) {
  866. auto web_contents =
  867. content::RenderViewHostTestHarness::CreateTestWebContents();
  868. ASSERT_EQ(ContentSubresourceFilterWebContentsHelper::FromWebContents(
  869. web_contents.get()),
  870. nullptr);
  871. ThrottleManagerTestSupport throttle_manager_test_support(web_contents.get());
  872. SubresourceFilterProfileContext* profile_context =
  873. throttle_manager_test_support.profile_context();
  874. {
  875. base::test::ScopedFeatureList scoped_feature;
  876. scoped_feature.InitAndDisableFeature(kSafeBrowsingSubresourceFilter);
  877. // CreateForWebContents() should not do anything if the subresource filter
  878. // feature is not enabled.
  879. ContentSubresourceFilterWebContentsHelper::CreateForWebContents(
  880. web_contents.get(), profile_context, /*database_manager=*/nullptr,
  881. dealer_handle());
  882. EXPECT_EQ(ContentSubresourceFilterWebContentsHelper::FromWebContents(
  883. web_contents.get()),
  884. nullptr);
  885. }
  886. // If the subresource filter feature is enabled (as it is by default),
  887. // CreateForWebContents() should create and attach an instance.
  888. ContentSubresourceFilterWebContentsHelper::CreateForWebContents(
  889. web_contents.get(), profile_context,
  890. /*database_manager=*/nullptr, dealer_handle());
  891. auto* helper = ContentSubresourceFilterWebContentsHelper::FromWebContents(
  892. web_contents.get());
  893. EXPECT_NE(helper, nullptr);
  894. // A second call should not attach a different instance.
  895. ContentSubresourceFilterWebContentsHelper::CreateForWebContents(
  896. web_contents.get(), profile_context,
  897. /*database_manager=*/nullptr, dealer_handle());
  898. EXPECT_EQ(ContentSubresourceFilterWebContentsHelper::FromWebContents(
  899. web_contents.get()),
  900. helper);
  901. }
  902. // Check to make sure we don't send an IPC with the ad tag bit for ad frames
  903. // that are successfully filtered.
  904. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  905. ActivateMainFrameAndFilterSubframeNavigationTaggedAsAd) {
  906. // Commit a navigation that triggers page level activation.
  907. NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
  908. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */,
  909. false /* is_ad_subframe */);
  910. // A disallowed subframe navigation should be successfully filtered.
  911. #if BUILDFLAG(IS_ANDROID)
  912. EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage);
  913. #endif
  914. CreateSubframeWithTestNavigation(
  915. GURL("https://www.example.com/disallowed.html"), main_rfh());
  916. EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
  917. SimulateStartAndGetResult(navigation_simulator()));
  918. EXPECT_TRUE(ads_blocked_in_content_settings());
  919. #if BUILDFLAG(IS_ANDROID)
  920. ::testing::Mock::VerifyAndClearExpectations(&message_dispatcher_bridge_);
  921. #endif
  922. }
  923. // If the RenderFrame determines that the frame is an ad due to creation by ad
  924. // script, then any navigation for that frame should be considered an ad.
  925. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  926. SubframeNavigationTaggedAsAdByRenderer) {
  927. NavigateAndCommitMainFrame(GURL(kTestURLWithDryRun));
  928. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */,
  929. false /* is_ad_subframe */);
  930. content::RenderFrameHost* subframe = CreateSubframeWithTestNavigation(
  931. GURL("https://www.example.com/allowed.html"), main_rfh());
  932. EXPECT_FALSE(throttle_manager()->IsRenderFrameHostTaggedAsAd(subframe));
  933. throttle_manager()->OnChildFrameWasCreatedByAdScript(subframe);
  934. throttle_manager()->OnFrameIsAdSubframe(subframe);
  935. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  936. SimulateStartAndGetResult(navigation_simulator()));
  937. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  938. SimulateCommitAndGetResult(navigation_simulator()));
  939. subframe = navigation_simulator()->GetFinalRenderFrameHost();
  940. EXPECT_TRUE(subframe);
  941. EXPECT_TRUE(throttle_manager()->IsRenderFrameHostTaggedAsAd(subframe));
  942. ExpectActivationSignalForFrame(subframe, true /* expect_activation */,
  943. true /* is_ad_subframe */);
  944. // A non-ad navigation for the same frame should be considered an ad
  945. // subframe as well.
  946. CreateTestNavigation(GURL("https://example.com/allowed2.html"), subframe);
  947. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  948. SimulateCommitAndGetResult(navigation_simulator()));
  949. subframe = navigation_simulator()->GetFinalRenderFrameHost();
  950. ExpectActivationSignalForFrame(subframe, true /* expect_activation */,
  951. true /* is_ad_subframe */);
  952. }
  953. // If the RenderFrame determines that the frame is an ad due to creation by ad
  954. // script, and the frame changes processes, then the frame should still be
  955. // considered an ad.
  956. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  957. AdTagCarriesAcrossProcesses) {
  958. content::IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
  959. NavigateAndCommitMainFrame(GURL(kTestURLWithDryRun));
  960. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */,
  961. false /* is_ad_subframe */);
  962. // Create a subframe to a different site. It will start as a same-process
  963. // frame but transition to a cross-process frame just before commit (after
  964. // the throttle has marked the frame as an ad.)
  965. content::RenderFrameHost* initial_subframe = CreateSubframeWithTestNavigation(
  966. GURL("https://www.example2.com/allowed.html"), main_rfh());
  967. // Simulate the render process telling the manager that the frame is an ad due
  968. // to creation by ad script.
  969. throttle_manager()->OnChildFrameWasCreatedByAdScript(initial_subframe);
  970. throttle_manager()->OnFrameIsAdSubframe(initial_subframe);
  971. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  972. SimulateStartAndGetResult(navigation_simulator()));
  973. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  974. SimulateCommitAndGetResult(navigation_simulator()));
  975. content::RenderFrameHost* final_subframe =
  976. navigation_simulator()->GetFinalRenderFrameHost();
  977. EXPECT_TRUE(final_subframe);
  978. EXPECT_NE(initial_subframe, final_subframe);
  979. EXPECT_TRUE(throttle_manager()->IsRenderFrameHostTaggedAsAd(final_subframe));
  980. ExpectActivationSignalForFrame(final_subframe, true /* expect_activation */,
  981. true /* is_ad_subframe */);
  982. }
  983. // If the RenderFrame determines that the frame was created by ad script, it
  984. // should be tagged and then its child frames should also be tagged as ads.
  985. TEST_P(ContentSubresourceFilterThrottleManagerTest,
  986. GrandchildNavigationTaggedAsAdByRenderer) {
  987. NavigateAndCommitMainFrame(GURL(kTestURLWithDryRun));
  988. ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */,
  989. false /* is_ad_subframe */);
  990. // Create a subframe that's marked as an ad by the render process.
  991. content::RenderFrameHost* subframe = CreateSubframeWithTestNavigation(
  992. GURL("https://www.example.com/allowed.html"), main_rfh());
  993. // Simulate the render process telling the manager that the frame is an ad due
  994. // to creation by ad script.
  995. throttle_manager()->OnChildFrameWasCreatedByAdScript(subframe);
  996. throttle_manager()->OnFrameIsAdSubframe(subframe);
  997. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  998. SimulateStartAndGetResult(navigation_simulator()));
  999. EXPECT_EQ(content::NavigationThrottle::PROCEED,
  1000. SimulateCommitAndGetResult(navigation_simulator()));
  1001. subframe = navigation_simulator()->GetFinalRenderFrameHost();
  1002. ExpectActivationSignalForFrame(subframe, true /* expect_activation */,
  1003. true /* is_ad_subframe */);
  1004. // Create a grand