diff --git a/browser/brave_browser_process.h b/browser/brave_browser_process.h index 303ca1a1fb71..206c83be3a40 100644 --- a/browser/brave_browser_process.h +++ b/browser/brave_browser_process.h @@ -32,8 +32,6 @@ class LocalDataFilesService; namespace brave_shields { class AdBlockService; -class AdBlockCustomFiltersService; -class AdBlockRegionalServiceManager; class HTTPSEverywhereService; } // namespace brave_shields @@ -77,10 +75,6 @@ class BraveBrowserProcess { virtual ~BraveBrowserProcess(); virtual void StartBraveServices() = 0; virtual brave_shields::AdBlockService* ad_block_service() = 0; - virtual brave_shields::AdBlockCustomFiltersService* - ad_block_custom_filters_service() = 0; - virtual brave_shields::AdBlockRegionalServiceManager* - ad_block_regional_service_manager() = 0; #if BUILDFLAG(ENABLE_EXTENSIONS) virtual brave_component_updater::ExtensionWhitelistService* extension_whitelist_service() = 0; diff --git a/browser/brave_browser_process_impl.cc b/browser/brave_browser_process_impl.cc index 17761ebcee32..3fdb88ac7983 100644 --- a/browser/brave_browser_process_impl.cc +++ b/browser/brave_browser_process_impl.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/path_service.h" #include "base/task/post_task.h" +#include "base/task/thread_pool.h" #include "brave/browser/brave_shields/ad_block_subscription_download_manager_getter.h" #include "brave/browser/brave_stats/brave_stats_updater.h" #include "brave/browser/component_updater/brave_component_updater_configurator.h" @@ -23,7 +24,6 @@ #include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h" #include "brave/components/brave_component_updater/browser/local_data_files_service.h" #include "brave/components/brave_referrals/buildflags/buildflags.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" #include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h" @@ -192,10 +192,14 @@ void BraveBrowserProcessImpl::StartBraveServices() { brave_shields::AdBlockService* BraveBrowserProcessImpl::ad_block_service() { if (!ad_block_service_) { + scoped_refptr task_runner( + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::USER_BLOCKING, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); ad_block_service_ = std::make_unique( - brave_component_updater_delegate(), + local_state(), GetApplicationLocale(), component_updater(), task_runner, std::make_unique( - brave_component_updater_delegate(), + local_state(), task_runner, AdBlockSubscriptionDownloadManagerGetter(), profile_manager()->user_data_dir().Append( profile_manager()->GetInitialProfileDir()))); @@ -203,16 +207,6 @@ brave_shields::AdBlockService* BraveBrowserProcessImpl::ad_block_service() { return ad_block_service_.get(); } -brave_shields::AdBlockCustomFiltersService* -BraveBrowserProcessImpl::ad_block_custom_filters_service() { - return ad_block_service()->custom_filters_service(); -} - -brave_shields::AdBlockRegionalServiceManager* -BraveBrowserProcessImpl::ad_block_regional_service_manager() { - return ad_block_service()->regional_service_manager(); -} - NTPBackgroundImagesService* BraveBrowserProcessImpl::ntp_background_images_service() { if (!ntp_background_images_service_) { @@ -262,9 +256,11 @@ BraveBrowserProcessImpl::debounce_component_installer() { brave_shields::HTTPSEverywhereService* BraveBrowserProcessImpl::https_everywhere_service() { - if (!https_everywhere_service_) + if (!created_https_everywhere_service_) { https_everywhere_service_ = brave_shields::HTTPSEverywhereServiceFactory( - brave_component_updater_delegate()); + brave_component_updater_delegate()->GetTaskRunner()); + created_https_everywhere_service_ = true; + } return https_everywhere_service_.get(); } diff --git a/browser/brave_browser_process_impl.h b/browser/brave_browser_process_impl.h index 37de5ae0bbf9..65fdeacaaec9 100644 --- a/browser/brave_browser_process_impl.h +++ b/browser/brave_browser_process_impl.h @@ -34,8 +34,6 @@ class LocalDataFilesService; namespace brave_shields { class AdBlockService; -class AdBlockCustomFiltersService; -class AdBlockRegionalServiceManager; class HTTPSEverywhereService; } // namespace brave_shields @@ -90,10 +88,6 @@ class BraveBrowserProcessImpl : public BraveBrowserProcess, void StartBraveServices() override; brave_shields::AdBlockService* ad_block_service() override; - brave_shields::AdBlockCustomFiltersService* ad_block_custom_filters_service() - override; - brave_shields::AdBlockRegionalServiceManager* - ad_block_regional_service_manager() override; #if BUILDFLAG(ENABLE_EXTENSIONS) brave_component_updater::ExtensionWhitelistService* extension_whitelist_service() override; @@ -155,6 +149,7 @@ class BraveBrowserProcessImpl : public BraveBrowserProcess, #endif std::unique_ptr debounce_component_installer_; + bool created_https_everywhere_service_ = false; std::unique_ptr https_everywhere_service_; std::unique_ptr brave_stats_updater_; diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index 07007ce79124..2809a389e099 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -876,7 +876,8 @@ BraveContentBrowserClient::CreateThrottlesForNavigation( content::NavigationThrottle> domain_block_navigation_throttle = brave_shields::DomainBlockNavigationThrottle::MaybeCreateThrottleFor( handle, g_brave_browser_process->ad_block_service(), - g_brave_browser_process->ad_block_custom_filters_service(), + g_brave_browser_process->ad_block_service() + ->custom_filters_provider(), EphemeralStorageServiceFactory::GetForContext(context), HostContentSettingsMapFactory::GetForProfile( Profile::FromBrowserContext(context)), diff --git a/browser/brave_shields/ad_block_service_browsertest.cc b/browser/brave_shields/ad_block_service_browsertest.cc index d89e029646af..c4a3bc642595 100644 --- a/browser/brave_shields/ad_block_service_browsertest.cc +++ b/browser/brave_shields/ad_block_service_browsertest.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "base/base64.h" @@ -21,11 +22,11 @@ #include "brave/common/brave_paths.h" #include "brave/common/pref_names.h" #include "brave/components/brave_component_updater/browser/local_data_files_service.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" -#include "brave/components/brave_shields/browser/ad_block_regional_service.h" +#include "brave/components/brave_shields/browser/ad_block_component_installer.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_default_filters_provider.h" #include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_service.h" -#include "brave/components/brave_shields/browser/ad_block_subscription_service.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager_observer.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" @@ -38,6 +39,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_test.h" @@ -79,6 +81,12 @@ using brave_shields::features::kBraveAdblockCookieListDefault; using brave_shields::features::kBraveAdblockCosmeticFiltering; using brave_shields::features::kBraveAdblockDefault1pBlocking; +AdBlockServiceTest::AdBlockServiceTest() { + brave_shields::SetDefaultAdBlockComponentIdAndBase64PublicKeyForTest( + kDefaultAdBlockComponentTestId, kDefaultAdBlockComponentTest64PublicKey); +} +AdBlockServiceTest::~AdBlockServiceTest() {} + void AdBlockServiceTest::SetUpOnMainThread() { ExtensionBrowserTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); @@ -92,7 +100,6 @@ void AdBlockServiceTest::SetUp() { void AdBlockServiceTest::PreRunTestOnMainThread() { ExtensionBrowserTest::PreRunTestOnMainThread(); WaitForAdBlockServiceThreads(); - ASSERT_TRUE(g_brave_browser_process->ad_block_service()->IsInitialized()); } HostContentSettingsMap* AdBlockServiceTest::content_settings() { @@ -102,23 +109,61 @@ HostContentSettingsMap* AdBlockServiceTest::content_settings() { void AdBlockServiceTest::UpdateAdBlockInstanceWithRules( const std::string& rules, const std::string& resources) { + auto source_provider = + std::make_unique(rules, resources); + brave_shields::AdBlockService* ad_block_service = g_brave_browser_process->ad_block_service(); - ad_block_service->GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&brave_shields::AdBlockService::ResetForTest, - base::Unretained(ad_block_service), rules, resources)); + ad_block_service->UseSourceProvidersForTest(source_provider.get(), + source_provider.get()); + + source_providers_.push_back(std::move(source_provider)); + + WaitForAdBlockServiceThreads(); +} + +void AdBlockServiceTest::UpdateAdBlockInstanceWithDAT( + const base::FilePath& dat_location, + const std::string& resources) { + base::ScopedAllowBlockingForTesting allow_blocking; + auto source_provider = std::make_unique( + dat_location, resources); + + brave_shields::AdBlockService* ad_block_service = + g_brave_browser_process->ad_block_service(); + ad_block_service->UseSourceProvidersForTest(source_provider.get(), + source_provider.get()); + + source_providers_.push_back(std::move(source_provider)); + + WaitForAdBlockServiceThreads(); +} + +void AdBlockServiceTest::UpdateCustomAdBlockInstanceWithRules( + const std::string& rules, + const std::string& resources) { + auto source_provider = + std::make_unique(rules, resources); + + brave_shields::AdBlockService* ad_block_service = + g_brave_browser_process->ad_block_service(); + ad_block_service->UseCustomSourceProvidersForTest(source_provider.get(), + source_provider.get()); + + source_providers_.push_back(std::move(source_provider)); + WaitForAdBlockServiceThreads(); } void AdBlockServiceTest::AssertTagExists(const std::string& tag, bool expected_exists) const { bool exists_default = - g_brave_browser_process->ad_block_service()->TagExists(tag); + g_brave_browser_process->ad_block_service()->TagExistsForTest(tag); ASSERT_EQ(exists_default, expected_exists); for (const auto& regional_service : - g_brave_browser_process->ad_block_regional_service_manager() + g_brave_browser_process->ad_block_service() + ->regional_service_manager() ->regional_services_) { bool exists_regional = regional_service.second->TagExists(tag); ASSERT_EQ(exists_regional, expected_exists); @@ -142,8 +187,6 @@ void AdBlockServiceTest::GetTestDataDir(base::FilePath* test_data_dir) { bool AdBlockServiceTest::InstallDefaultAdBlockExtension( const std::string& extension_dir, int expected_change) { - brave_shields::AdBlockService::SetComponentIdAndBase64PublicKeyForTest( - kDefaultAdBlockComponentTestId, kDefaultAdBlockComponentTest64PublicKey); base::FilePath test_data_dir; GetTestDataDir(&test_data_dir); const extensions::Extension* ad_block_extension = InstallExtension( @@ -152,69 +195,91 @@ bool AdBlockServiceTest::InstallDefaultAdBlockExtension( if (!ad_block_extension) return false; - g_brave_browser_process->ad_block_service()->OnComponentReady( - ad_block_extension->id(), ad_block_extension->path(), ""); + g_brave_browser_process->ad_block_service() + ->default_filters_provider_->OnComponentReady(ad_block_extension->path()); WaitForAdBlockServiceThreads(); return true; } +// A test observer that allows blocking waits for an AdBlockEngine to be +// updated with new rules. +class EngineTestObserver : public brave_shields::AdBlockEngine::TestObserver { + public: + // Constructs an EngineTestObserver which will observe the given adblock + // engine for filter data updates. + explicit EngineTestObserver(brave_shields::AdBlockEngine* engine) + : engine_(engine) { + engine_->AddObserverForTest(this); + } + ~EngineTestObserver() override { engine_->RemoveObserverForTest(); } + + EngineTestObserver(const EngineTestObserver& other) = delete; + EngineTestObserver& operator=(const EngineTestObserver& other) = delete; + + // Blocks until the engine is updated + void Wait() { run_loop_.Run(); } + + private: + void OnEngineUpdated() override { run_loop_.Quit(); } + + base::RunLoop run_loop_; + raw_ptr engine_ = nullptr; +}; + bool AdBlockServiceTest::InstallRegionalAdBlockExtension( - const std::string& uuid) { - brave_shields::AdBlockRegionalService:: - SetComponentIdAndBase64PublicKeyForTest( - kRegionalAdBlockComponentTestId, - kRegionalAdBlockComponentTest64PublicKey); + const std::string& uuid, + bool enable_list) { + // The regional adblock engines depend on the default engine for resource + // loads. + EXPECT_TRUE(InstallDefaultAdBlockExtension()); + auto* default_engine = + g_brave_browser_process->ad_block_service()->default_service_.get(); + EngineTestObserver default_engine_observer(default_engine); + default_engine_observer.Wait(); + base::FilePath test_data_dir; GetTestDataDir(&test_data_dir); std::vector regional_catalog; regional_catalog.push_back(adblock::FilterList( uuid, "https://easylist-downloads.adblockplus.org/liste_fr.txt", "EasyList Liste FR", {"fr"}, "https://forums.lanik.us/viewforum.php?f=91", - "emaecjinaegfkoklcdafkiocjhoeilao", - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsbqIWuMS7r2OPXCsIPbbLG1H" - "/" - "d3NM9uzCMscw7R9ZV3TwhygvMOpZrNp4Y4hImy2H+HE0OniCqzuOAaq7+" - "SHXcdHwItvLK" - "tnRmeWgdqxgEdzJ8rZMWnfi+dODTbA4QvxI6itU5of8trDFbLzFqgnEOBk8ZxtjM/" - "M5v3" - "UeYh+EYHSEyHnDSJKbKevlXC931xlbdca0q0Ps3Ln6w/pJFByGbOh212mD/" - "PvwS6jIH3L" - "YjrMVUMefKC/ywn/AAdnwM5mGirm1NflQCJQOpTjIhbRIXBlACfV/" - "hwI1lqfKbFnyr4aP" - "Odg3JcOZZVoyi+ko3rKG3vH9JPWEy24Ys9A3SYpTwIDAQAB", + kRegionalAdBlockComponentTestId, kRegionalAdBlockComponentTest64PublicKey, "Removes advertisements from French websites")); - g_brave_browser_process->ad_block_regional_service_manager() + g_brave_browser_process->ad_block_service() + ->regional_service_manager() ->SetRegionalCatalog(regional_catalog); - const extensions::Extension* ad_block_extension = - InstallExtension(test_data_dir.AppendASCII("adblock-data") - .AppendASCII("adblock-regional") - .AppendASCII(uuid), - 1); - if (!ad_block_extension) - return false; - g_brave_browser_process->ad_block_regional_service_manager() - ->EnableFilterList(uuid, true); - EXPECT_EQ(g_brave_browser_process->ad_block_regional_service_manager() - ->regional_services_.size(), - 1ULL); - - auto regional_service = - g_brave_browser_process->ad_block_regional_service_manager() - ->regional_services_.find(uuid); - regional_service->second->OnComponentReady(ad_block_extension->id(), - ad_block_extension->path(), ""); - WaitForAdBlockServiceThreads(); - - return true; -} + if (enable_list) { + const extensions::Extension* ad_block_extension = + InstallExtension(test_data_dir.AppendASCII("adblock-data") + .AppendASCII("adblock-regional") + .AppendASCII(uuid), + 1); + if (!ad_block_extension) + return false; + + g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->EnableFilterList(uuid, true); + EXPECT_EQ(g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->regional_services_.size(), + 1ULL); + + auto regional_engine = g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->regional_services_.find(uuid); + EngineTestObserver regional_engine_observer(regional_engine->second.get()); + auto regional_filters_provider = + g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->regional_filters_providers_.find(uuid); + regional_filters_provider->second->OnComponentReady( + ad_block_extension->path()); + regional_engine_observer.Wait(); + } -bool AdBlockServiceTest::StartAdBlockRegionalServices() { - g_brave_browser_process->ad_block_regional_service_manager()->Start(); - if (!g_brave_browser_process->ad_block_regional_service_manager() - ->IsInitialized()) - return false; return true; } @@ -226,34 +291,20 @@ void AdBlockServiceTest::SetSubscriptionIntervals() { auto* subscription_service_manager = ad_block_service->subscription_service_manager(); - ASSERT_TRUE(ad_block_service->IsInitialized()); - subscription_service_manager->SetUpdateIntervalsForTesting(&initial_delay, &retry_interval); } void AdBlockServiceTest::WaitForAdBlockServiceThreads() { scoped_refptr tr_helper(new base::ThreadTestHelper( - g_brave_browser_process->local_data_files_service()->GetTaskRunner())); + g_brave_browser_process->ad_block_service()->GetTaskRunner())); ASSERT_TRUE(tr_helper->Run()); } -void AdBlockServiceTest::WaitForBraveExtensionShieldsDataReady() { - // Sometimes, the page can start loading before the Shields panel has - // received information about the window and tab it's loaded in. - ExtensionTestMessageListener extension_listener( - "brave-extension-shields-data-ready", false); - ASSERT_TRUE(extension_listener.WaitUntilSatisfied()); -} - void AdBlockServiceTest::ShieldsDown(const GURL& url) { brave_shields::SetBraveShieldsEnabled(content_settings(), false, url); } -void AdBlockServiceTest::LoadDAT(const base::FilePath path) { - g_brave_browser_process->ad_block_service()->GetDATFileData(path); -} - // Load a page with an ad image, and make sure it is blocked. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdsGetBlockedByDefaultBlocker) { ASSERT_TRUE(InstallDefaultAdBlockExtension()); @@ -274,8 +325,8 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdsGetBlockedByDefaultBlocker) { // blocked by custom filters. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, NotAdsDoNotGetBlockedByCustomBlocker) { - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters("*ad_banner.png")); + ASSERT_TRUE(InstallDefaultAdBlockExtension()); + UpdateCustomAdBlockInstanceWithRules("*ad_banner.png"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -293,13 +344,12 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, // Load a page with an ad image, and make sure it is blocked by custom // filters. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdsGetBlockedByCustomBlocker) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); - ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules(""); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters("*ad_banner.png")); + UpdateCustomAdBlockInstanceWithRules("*ad_banner.png"); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -315,13 +365,11 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdsGetBlockedByCustomBlocker) { // Load a page with an ad image, with a corresponding exception installed in // the custom filters, and make sure it is not blocked. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, DefaultBlockCustomException) { - EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); - ASSERT_TRUE(InstallDefaultAdBlockExtension()); + EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); UpdateAdBlockInstanceWithRules("*ad_banner.png"); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters("@@ad_banner.png")); + UpdateCustomAdBlockInstanceWithRules("@@ad_banner.png"); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -337,10 +385,10 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, DefaultBlockCustomException) { // Load a page with an image blocked by custom filters, with a corresponding // exception installed in the default filters, and make sure it is not blocked. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CustomBlockDefaultException) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); UpdateAdBlockInstanceWithRules("@@ad_banner.png"); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters("*ad_banner.png")); + UpdateCustomAdBlockInstanceWithRules("*ad_banner.png"); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -380,7 +428,6 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdsGetBlockedByRegionalBlocker) { EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); ASSERT_TRUE(InstallRegionalAdBlockExtension(kAdBlockEasyListFranceUUID)); - ASSERT_TRUE(StartAdBlockRegionalServices()); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -403,7 +450,6 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); ASSERT_TRUE(InstallRegionalAdBlockExtension(kAdBlockEasyListFranceUUID)); - ASSERT_TRUE(StartAdBlockRegionalServices()); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -580,6 +626,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SubFrameShieldsOff) { // Requests made by a service worker should be blocked as well. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, ServiceWorkerRequest) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("adbanner.js"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -601,14 +648,13 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, ServiceWorkerRequest) { // the start it adds an exception rule to the non regional adblocker. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, ExceptionAdsAreAllowedAcrossClients) { - UpdateAdBlockInstanceWithRules("*ad_fr*\n@@*ad_fr.png*"); g_browser_process->SetApplicationLocale("fr"); ASSERT_STREQ(g_browser_process->GetApplicationLocale().c_str(), "fr"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); ASSERT_TRUE(InstallRegionalAdBlockExtension(kAdBlockEasyListFranceUUID)); - ASSERT_TRUE(StartAdBlockRegionalServices()); + UpdateAdBlockInstanceWithRules("*ad_fr*\n@@*ad_fr.png*"); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); @@ -622,6 +668,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, // Make sure the third-party flag is passed into the ad-block library properly IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdBlockThirdPartyWorksByETLDP1) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||a.com$third-party"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -641,6 +688,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdBlockThirdPartyWorksByETLDP1) { // Make sure the third-party flag is passed into the ad-block library properly IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, AdBlockThirdPartyWorksForThirdPartyHost) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||a.com$third-party"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL tab_url = embedded_test_server()->GetURL("b.com", kAdBlockTestPage); @@ -716,6 +764,7 @@ class TestAdBlockSubscriptionServiceManagerObserver // although it doesn't seem to occur in real usage. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, MAYBE_SubscribeToCustomSubscription) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL subscription_url = embedded_test_server()->GetURL("lists.com", "/list.txt"); @@ -819,6 +868,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, // Make sure the state of a list that cannot be fetched is as expected IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SubscribeTo404List) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL subscription_url = embedded_test_server()->GetURL("lists.com", "/this/list/does/not/exist"); @@ -863,6 +913,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SubscribeTo404List) { // Make sure that a list cannot be subscribed to twice IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SubscribeToListUrlTwice) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL subscription_url = embedded_test_server()->GetURL("lists.com", "/this/list/does/not/exist"); @@ -905,6 +956,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SubscribeToListUrlTwice) { // issue the correct number of DNS resolutions IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, MAYBE_CnameCloakedRequestsGetBlocked) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||cname-cloak-endpoint.tracking.com^"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL tab_url = embedded_test_server()->GetURL("a.com", kAdBlockTestPage); @@ -990,6 +1042,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, // to its CNAME-uncloaked equivalent. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, MAYBE_CnameCloakedRequestsCanBeExcepted) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "||cname-cloak-endpoint.tracking.com^\n" "@@||a.com/logo-unblock.png|"); @@ -1086,6 +1139,7 @@ class CnameUncloakingFlagDisabledTest : public AdBlockServiceTest { // Make sure that CNAME uncloaking does not occur when the CNAME uncloaking // flag is disabled. IN_PROC_BROWSER_TEST_F(CnameUncloakingFlagDisabledTest, NoDnsQueriesIssued) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||cname-cloak-endpoint.tracking.com^"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL tab_url = embedded_test_server()->GetURL("a.com", kAdBlockTestPage); @@ -1167,6 +1221,7 @@ IN_PROC_BROWSER_TEST_F(CnameUncloakingFlagDisabledTest, NoDnsQueriesIssued) { // Load an image from a specific subdomain, and make sure it is blocked. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, BlockNYP) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||sp1.nypost.com$third-party"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL tab_url = embedded_test_server()->GetURL("b.com", kAdBlockTestPage); @@ -1184,6 +1239,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, BlockNYP) { // Frame root URL is used for context rather than the tab URL IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, FrameSourceURL) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("adbanner.js$domain=a.com"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL url = embedded_test_server()->GetURL("a.com", "/iframe_blocking.html"); @@ -1208,6 +1264,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, FrameSourceURL) { // Tags for social buttons work IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SocialButttonAdBlockTagTest) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( base::StringPrintf("||example.com^$tag=%s", brave_shields::kFacebookEmbeds) @@ -1231,6 +1288,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SocialButttonAdBlockTagTest) { // Lack of tags for social buttons work IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SocialButttonAdBlockDiffTagTest) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("||example.com^$tag=sup"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); GURL tab_url = embedded_test_server()->GetURL("b.com", kAdBlockTestPage); @@ -1251,6 +1309,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, SocialButttonAdBlockDiffTagTest) { // Tags are preserved after resetting IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, ResetPreservesTags) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); g_brave_browser_process->ad_block_service()->EnableTag( brave_shields::kFacebookEmbeds, true); WaitForAdBlockServiceThreads(); @@ -1420,6 +1479,7 @@ class Default1pBlockingFlagDisabledTest : public AdBlockServiceTest { // match the same filter in the default engine. Ensure the third-party one is // blocked while the first-party one is allowed. IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, Default1pBlocking) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); UpdateAdBlockInstanceWithRules("^ad_banner.png"); @@ -1444,6 +1504,7 @@ IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, Default1pBlocking) { // ensure that both are blocked. IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, Aggressive1pBlocking) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); brave_shields::SetCosmeticFilteringControlType( content_settings(), brave_shields::ControlType::BLOCK, GURL()); @@ -1469,9 +1530,9 @@ IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, // match the same filter in the custom filters engine. Ensure that both are // blocked. IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, Custom1pBlocking) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters("^ad_banner.png")); + UpdateCustomAdBlockInstanceWithRules("^ad_banner.png"); WaitForAdBlockServiceThreads(); GURL url = embedded_test_server()->GetURL(kAdBlockTestPage); @@ -1492,6 +1553,7 @@ IN_PROC_BROWSER_TEST_F(Default1pBlockingFlagDisabledTest, Custom1pBlocking) { // Load a page with a script which uses a redirect data URL. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, RedirectRulesAreRespected) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("js_mock_me.js$redirect=noopjs", R"( [ @@ -1526,6 +1588,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, RedirectRulesAreRespected) { // A redirection should only be applied if there's also a matching blocking // rule. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, RedirectWithoutBlockIsNoop) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); // The DAT for this test contains the following rules: // .js?block=true // js_mock_me.js$redirect-rule=noopjs @@ -1534,16 +1597,19 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, RedirectWithoutBlockIsNoop) { // packager eventually begins shipping DATs that include them. base::FilePath test_data_dir; GetTestDataDir(&test_data_dir); - LoadDAT(test_data_dir.AppendASCII("adblock-data") - .AppendASCII("redirect-rule.dat")); - g_brave_browser_process->ad_block_service()->AddResources(R"([{ + + base::FilePath dat_location = test_data_dir.AppendASCII("adblock-data") + .AppendASCII("redirect-rule.dat"); + std::string resources = R"([{ "name": "noop.js", "aliases": ["noopjs"], "kind": { "mime":"application/javascript" }, "content": "KGZ1bmN0aW9uKCkgewogICAgJ3VzZSBzdHJpY3QnOwp9KSgpOwo=" - }])"); + }])"; + UpdateAdBlockInstanceWithDAT(dat_location, resources); + WaitForAdBlockServiceThreads(); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -1578,6 +1644,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, RedirectWithoutBlockIsNoop) { // Verify that scripts violating a Content Security Policy from a `$csp` rule // are not loaded. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CspRule) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "||example.com^$csp=script-src 'nonce-abcdef' 'unsafe-eval' 'self'"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -1606,13 +1673,13 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CspRule) { // The policy resulting from two of the same kind of directive will be the // union of both. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CspRuleMerging) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "||example.com^$csp=script-src 'nonce-abcdef' 'unsafe-eval' 'self'"); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() - ->UpdateCustomFilters( - "||example.com^$csp=img-src 'none'\n" - "||sub.example.com^$csp=script-src 'nonce-abcdef' " - "'unsafe-eval' 'unsafe-inline'")); + UpdateCustomAdBlockInstanceWithRules( + "||example.com^$csp=img-src 'none'\n" + "||sub.example.com^$csp=script-src 'nonce-abcdef' " + "'unsafe-eval' 'unsafe-inline'"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); const GURL url = @@ -1636,6 +1703,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CspRuleMerging) { // Verify that scripts violating a Content Security Policy from a `$csp` rule // are not loaded. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CspRuleShieldsDown) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "||example.com^$csp=script-src 'nonce-abcdef' 'unsafe-eval' 'self'"); EXPECT_EQ(browser()->profile()->GetPrefs()->GetUint64(kAdsBlocked), 0ULL); @@ -1672,10 +1740,10 @@ class CosmeticFilteringFlagDisabledTest : public AdBlockServiceTest { // Ensure no cosmetic filtering occurs when the feature flag is disabled IN_PROC_BROWSER_TEST_F(CosmeticFilteringFlagDisabledTest, CosmeticFilteringSimple) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "b.com###ad-banner\n" "##.ad"); - WaitForBraveExtensionShieldsDataReady(); GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); @@ -1695,14 +1763,13 @@ IN_PROC_BROWSER_TEST_F(CosmeticFilteringFlagDisabledTest, // Ensure no cosmetic filtering occurs when the shields setting is disabled IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDisabled) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); brave_shields::SetCosmeticFilteringControlType( content_settings(), brave_shields::ControlType::ALLOW, GURL()); UpdateAdBlockInstanceWithRules( "b.com###ad-banner\n" "##.ad"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1721,12 +1788,11 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDisabled) { // Test simple cosmetic filtering IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringSimple) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "b.com###ad-banner\n" "##.ad"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1776,6 +1842,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringSimple) { // Test cosmetic filtering ignores content determined to be 1st party IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringProtect1p) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "appspot.com##.fpsponsored\n" "appspot.com##.fpsponsored1\n" @@ -1783,8 +1850,6 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringProtect1p) { "appspot.com##.fpsponsored3\n" "appspot.com##.fpsponsored4\n"); - WaitForBraveExtensionShieldsDataReady(); - // *.appspot.com is used here to check the eTLD logic. // It's a private suffix from https://publicsuffix.org/list/ GURL tab_url = embedded_test_server()->GetURL("test.lion.appspot.com", @@ -1811,12 +1876,11 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringProtect1p) { // Test cosmetic filtering bypasses 1st party checks when toggled IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringHide1pContent) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); brave_shields::SetCosmeticFilteringControlType( content_settings(), brave_shields::ControlType::BLOCK, GURL()); UpdateAdBlockInstanceWithRules("b.com##.fpsponsored\n"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1840,10 +1904,9 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringHide1pContent) { // Test cosmetic filtering on elements added dynamically IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDynamic) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("##.blockme"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1882,11 +1945,11 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDynamic) { // Test cosmetic filtering on elements added dynamically, using a rule from the // custom filters IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDynamicCustom) { - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() + ASSERT_TRUE(InstallDefaultAdBlockExtension()); + ASSERT_TRUE(g_brave_browser_process->ad_block_service() + ->custom_filters_provider() ->UpdateCustomFilters("##.blockme")); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1926,13 +1989,12 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringDynamicCustom) { // `generichide` exception rule, both for elements added dynamically and // elements present at page load IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringGenerichide) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "##.blockme\n" "##img[src=\"https://example.com/logo.png\"]\n" "@@||b.com$generichide"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1952,10 +2014,9 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringGenerichide) { // Test custom style rules IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringCustomStyle) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("b.com##.ad:style(padding-bottom: 10px)"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -1979,14 +2040,13 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringCustomStyle) { // Test rules overridden by hostname-specific exception rules IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringUnhide) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules( "##.ad\n" "b.com#@#.ad\n" "###ad-banner\n" "a.com#@##ad-banner"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -2023,6 +2083,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringUnhide) { // Test scriptlet injection that modifies window attributes IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringWindowScriptlet) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); /* "content" below corresponds to the following scriptlet: * ``` * (function() { @@ -2044,8 +2105,6 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringWindowScriptlet) { "uKHNlbGVjdG9yKSB7CiAgICByZXR1cm4geyAnY29sb3InOiAnSW1wb3NzaWJsZSB2YW" "x1ZScgfTsKICB9Cn0pKCk7Cg==\"}]"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -2069,6 +2128,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringWindowScriptlet) { // Test scriptlet injection that modifies window attributes IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringIframeScriptlet) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); std::string scriptlet = "(function() {" " window.JSON.parse = function() { return {} }" @@ -2084,8 +2144,6 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringIframeScriptlet) { "\"content\": \"" + scriptlet_base64 + "\"}]"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/iframe_messenger.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -2100,10 +2158,9 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringIframeScriptlet) { // marker on its `display` style. IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringOverridesImportant) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); UpdateAdBlockInstanceWithRules("###inline-block-important"); - WaitForBraveExtensionShieldsDataReady(); - GURL tab_url = embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); @@ -2135,36 +2192,40 @@ class DefaultCookieListFlagEnabledTest : public AdBlockServiceTest { base::test::ScopedFeatureList feature_list_; }; +class CookieListPrefObserver { + public: + explicit CookieListPrefObserver(PrefService* local_state) { + pref_change_registrar_.Init(local_state); + pref_change_registrar_.Add( + brave_shields::prefs::kAdBlockRegionalFilters, + base::BindRepeating(&CookieListPrefObserver::OnUpdated, + base::Unretained(this))); + } + ~CookieListPrefObserver() {} + + CookieListPrefObserver(const CookieListPrefObserver& other) = delete; + CookieListPrefObserver& operator=(const CookieListPrefObserver& other) = + delete; + + void Wait() { run_loop_.Run(); } + + private: + void OnUpdated() { run_loop_.Quit(); } + + base::RunLoop run_loop_; + PrefChangeRegistrar pref_change_registrar_; +}; + // Test that the `brave-adblock-default-1p-blocking` flag forces the Cookie // List UUID to be enabled, until manually enabled and then disabled again. -IN_PROC_BROWSER_TEST_F(DefaultCookieListFlagEnabledTest, - CosmeticFilteringIframeScriptlet) { - std::vector regional_catalog = - std::vector(); - regional_catalog.push_back(adblock::FilterList( - brave_shields::kCookieListUuid, - "https://easylist-downloads.adblockplus.org/liste_fr.txt", - "EasyList Liste FR", {"fr"}, "https://forums.lanik.us/viewforum.php?f=91", - "emaecjinaegfkoklcdafkiocjhoeilao", - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsbqIWuMS7r2OPXCsIPbbLG1H" - "/" - "d3NM9uzCMscw7R9ZV3TwhygvMOpZrNp4Y4hImy2H+HE0OniCqzuOAaq7+" - "SHXcdHwItvLK" - "tnRmeWgdqxgEdzJ8rZMWnfi+dODTbA4QvxI6itU5of8trDFbLzFqgnEOBk8ZxtjM/" - "M5v3" - "UeYh+EYHSEyHnDSJKbKevlXC931xlbdca0q0Ps3Ln6w/pJFByGbOh212mD/" - "PvwS6jIH3L" - "YjrMVUMefKC/ywn/AAdnwM5mGirm1NflQCJQOpTjIhbRIXBlACfV/" - "hwI1lqfKbFnyr4aP" - "Odg3JcOZZVoyi+ko3rKG3vH9JPWEy24Ys9A3SYpTwIDAQAB", - "Removes advertisements from French websites")); - g_brave_browser_process->ad_block_regional_service_manager() - ->SetRegionalCatalog(regional_catalog); +IN_PROC_BROWSER_TEST_F(DefaultCookieListFlagEnabledTest, ListEnabled) { + ASSERT_TRUE( + InstallRegionalAdBlockExtension(brave_shields::kCookieListUuid, false)); { - const auto lists = - g_brave_browser_process->ad_block_regional_service_manager() - ->GetRegionalLists(); + const auto lists = g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->GetRegionalLists(); // Although never explicitly enabled, it should be presented as enabled by // default at first. ASSERT_EQ(1UL, lists->GetList().size()); @@ -2172,17 +2233,25 @@ IN_PROC_BROWSER_TEST_F(DefaultCookieListFlagEnabledTest, } // Enable the filter list, and then disable it again. - g_brave_browser_process->ad_block_regional_service_manager() - ->EnableFilterList(brave_shields::kCookieListUuid, true); - g_brave_browser_process->ad_block_regional_service_manager() - ->EnableFilterList(brave_shields::kCookieListUuid, false); - - WaitForBraveExtensionShieldsDataReady(); + { + g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->EnableFilterList(brave_shields::kCookieListUuid, true); + CookieListPrefObserver pref_observer(g_browser_process->local_state()); + pref_observer.Wait(); + } + { + g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->EnableFilterList(brave_shields::kCookieListUuid, false); + CookieListPrefObserver pref_observer(g_browser_process->local_state()); + pref_observer.Wait(); + } { - const auto lists = - g_brave_browser_process->ad_block_regional_service_manager() - ->GetRegionalLists(); + const auto lists = g_brave_browser_process->ad_block_service() + ->regional_service_manager() + ->GetRegionalLists(); // It should be actually disabled now. ASSERT_EQ(1UL, lists->GetList().size()); EXPECT_EQ(false, lists->GetList()[0].FindKey("enabled")->GetBool()); diff --git a/browser/brave_shields/ad_block_service_browsertest.h b/browser/brave_shields/ad_block_service_browsertest.h index 1a2e48c0ff02..187f08ce44ea 100644 --- a/browser/brave_shields/ad_block_service_browsertest.h +++ b/browser/brave_shields/ad_block_service_browsertest.h @@ -6,16 +6,24 @@ #ifndef BRAVE_BROWSER_BRAVE_SHIELDS_AD_BLOCK_SERVICE_BROWSERTEST_H_ #define BRAVE_BROWSER_BRAVE_SHIELDS_AD_BLOCK_SERVICE_BROWSERTEST_H_ +#include #include +#include +#include "brave/components/brave_shields/browser/test_filters_provider.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "content/public/test/content_mock_cert_verifier.h" class HostContentSettingsMap; +namespace brave_shields { +class AdBlockService; +} // namespace brave_shields + class AdBlockServiceTest : public extensions::ExtensionBrowserTest { public: - AdBlockServiceTest() {} + AdBlockServiceTest(); + ~AdBlockServiceTest() override; // ExtensionBrowserTest overrides void SetUpOnMainThread() override; @@ -27,7 +35,12 @@ class AdBlockServiceTest : public extensions::ExtensionBrowserTest { HostContentSettingsMap* content_settings(); void UpdateAdBlockInstanceWithRules(const std::string& rules, - const std::string& resources = ""); + const std::string& resources = "[]"); + void UpdateAdBlockInstanceWithDAT(const base::FilePath& dat_location, + const std::string& resources = "[]"); + void UpdateCustomAdBlockInstanceWithRules( + const std::string& rules, + const std::string& resources = "[]"); void AssertTagExists(const std::string& tag, bool expected_exists) const; void InitEmbeddedTestServer(); void GetTestDataDir(base::FilePath* test_data_dir); @@ -36,13 +49,16 @@ class AdBlockServiceTest : public extensions::ExtensionBrowserTest { bool InstallDefaultAdBlockExtension( const std::string& extension_dir = "adblock-default", int expected_change = 1); - bool InstallRegionalAdBlockExtension(const std::string& uuid); - bool StartAdBlockRegionalServices(); + bool InstallRegionalAdBlockExtension(const std::string& uuid, + bool enable_list = true); void SetSubscriptionIntervals(); void WaitForAdBlockServiceThreads(); - void WaitForBraveExtensionShieldsDataReady(); void ShieldsDown(const GURL& url); void LoadDAT(base::FilePath path); + void EnableRedirectUrlParsing(); + + std::vector> + source_providers_; }; #endif // BRAVE_BROWSER_BRAVE_SHIELDS_AD_BLOCK_SERVICE_BROWSERTEST_H_ diff --git a/browser/brave_shields/domain_block_page_browsertest.cc b/browser/brave_shields/domain_block_page_browsertest.cc index 3a952757492b..5cdc15351a05 100644 --- a/browser/brave_shields/domain_block_page_browsertest.cc +++ b/browser/brave_shields/domain_block_page_browsertest.cc @@ -8,7 +8,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "brave/browser/brave_browser_process.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" #include "brave/components/brave_shields/common/features.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -318,7 +319,8 @@ IN_PROC_BROWSER_TEST_F(DomainBlockTest, NoFetch) { IN_PROC_BROWSER_TEST_F(DomainBlockTest, NoThirdPartyInterstitial) { ASSERT_TRUE(InstallDefaultAdBlockExtension()); - ASSERT_TRUE(g_brave_browser_process->ad_block_custom_filters_service() + ASSERT_TRUE(g_brave_browser_process->ad_block_service() + ->custom_filters_provider() ->UpdateCustomFilters("||b.com^$third-party")); GURL url = embedded_test_server()->GetURL("a.com", "/simple_link.html"); diff --git a/browser/brave_shields/https_everywhere_component_installer.cc b/browser/brave_shields/https_everywhere_component_installer.cc new file mode 100644 index 000000000000..65d7b096c900 --- /dev/null +++ b/browser/brave_shields/https_everywhere_component_installer.cc @@ -0,0 +1,184 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/brave_shields/https_everywhere_component_installer.h" + +#include +#include +#include + +#include "base/base64.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/no_destructor.h" +#include "brave/browser/brave_browser_process.h" +#include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h" +#include "brave/components/brave_shields/browser/https_everywhere_service.h" +#include "chrome/browser/browser_process.h" +#include "components/component_updater/component_installer.h" +#include "components/component_updater/component_updater_service.h" +#include "crypto/sha2.h" + +using brave_component_updater::BraveOnDemandUpdater; + +namespace brave_shields { + +namespace { + +constexpr size_t kHashSize = 32; +const char kHTTPSEverywhereComponentName[] = "Brave HTTPS Everywhere Updater"; +const char kHTTPSEverywhereComponentId[] = "oofiananboodjbbmdelgdommihjbkfag"; +const char kHTTPSEverywhereComponentBase64PublicKey[] = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvn9zSMjTmhkQyrZu5UdN" + "350nPqLoSeCYngcC7yDFwaUHjoBQXCZqGeDC69ciCQ2mlRhcV2nxXqlUDkiC6+7m" + "651nI+gi4oVqHagc7EFUyGA0yuIk7qIMvCBdH7wbET27de0rzbRzRht9EKzEjIhC" + "BtoPnmyrO/8qPrH4XR4cPfnFPuJssBBxC1B35H7rh0Br9qePhPDDe9OjyqYxPuio" + "+YcC9obL4g5krVrfrlKLfFNpIewUcJyBpSlCgfxEyEhgDkK9cILTMUi5vC7GxS3P" + "OtZqgfRg8Da4i+NwmjQqrz0JFtPMMSyUnmeMj+mSOL4xZVWr8fU2/GOCXs9gczDp" + "JwIDAQAB"; + +class HTTPSEverywhereComponentInstallerPolicy + : public component_updater::ComponentInstallerPolicy { + public: + HTTPSEverywhereComponentInstallerPolicy(); + ~HTTPSEverywhereComponentInstallerPolicy() override; + + HTTPSEverywhereComponentInstallerPolicy( + const HTTPSEverywhereComponentInstallerPolicy&) = delete; + HTTPSEverywhereComponentInstallerPolicy& operator=( + const HTTPSEverywhereComponentInstallerPolicy&) = delete; + + // component_updater::ComponentInstallerPolicy + bool SupportsGroupPolicyEnabledComponentUpdates() const override; + bool RequiresNetworkEncryption() const override; + update_client::CrxInstaller::Result OnCustomInstall( + const base::Value& manifest, + const base::FilePath& install_dir) override; + void OnCustomUninstall() override; + bool VerifyInstallation(const base::Value& manifest, + const base::FilePath& install_dir) const override; + void ComponentReady(const base::Version& version, + const base::FilePath& path, + base::Value manifest) override; + base::FilePath GetRelativeInstallDir() const override; + void GetHash(std::vector* hash) const override; + std::string GetName() const override; + update_client::InstallerAttributes GetInstallerAttributes() const override; + + static base::NoDestructor g_https_everywhere_component_id_; + static base::NoDestructor + g_https_everywhere_component_base64_public_key_; + + private: + const std::string component_id_; + const std::string component_name_; + uint8_t component_hash_[kHashSize]; +}; + +base::NoDestructor + HTTPSEverywhereComponentInstallerPolicy::g_https_everywhere_component_id_( + kHTTPSEverywhereComponentId); +base::NoDestructor HTTPSEverywhereComponentInstallerPolicy:: + g_https_everywhere_component_base64_public_key_( + kHTTPSEverywhereComponentBase64PublicKey); + +HTTPSEverywhereComponentInstallerPolicy:: + HTTPSEverywhereComponentInstallerPolicy() + : component_id_(kHTTPSEverywhereComponentId), + component_name_(kHTTPSEverywhereComponentName) { + // Generate hash from public key. + std::string decoded_public_key; + base::Base64Decode(kHTTPSEverywhereComponentBase64PublicKey, + &decoded_public_key); + crypto::SHA256HashString(decoded_public_key, component_hash_, kHashSize); +} + +HTTPSEverywhereComponentInstallerPolicy:: + ~HTTPSEverywhereComponentInstallerPolicy() = default; + +bool HTTPSEverywhereComponentInstallerPolicy:: + SupportsGroupPolicyEnabledComponentUpdates() const { + return true; +} + +bool HTTPSEverywhereComponentInstallerPolicy::RequiresNetworkEncryption() + const { + return false; +} + +update_client::CrxInstaller::Result +HTTPSEverywhereComponentInstallerPolicy::OnCustomInstall( + const base::Value& manifest, + const base::FilePath& install_dir) { + return update_client::CrxInstaller::Result(0); +} + +void HTTPSEverywhereComponentInstallerPolicy::OnCustomUninstall() {} + +void HTTPSEverywhereComponentInstallerPolicy::ComponentReady( + const base::Version& version, + const base::FilePath& path, + base::Value manifest) { + if (g_browser_process->IsShuttingDown()) + return; + + g_brave_browser_process->https_everywhere_service()->InitDB(path); +} + +bool HTTPSEverywhereComponentInstallerPolicy::VerifyInstallation( + const base::Value& manifest, + const base::FilePath& install_dir) const { + return true; +} + +base::FilePath HTTPSEverywhereComponentInstallerPolicy::GetRelativeInstallDir() + const { + return base::FilePath::FromUTF8Unsafe(component_id_); +} + +void HTTPSEverywhereComponentInstallerPolicy::GetHash( + std::vector* hash) const { + hash->assign(component_hash_, component_hash_ + kHashSize); +} + +std::string HTTPSEverywhereComponentInstallerPolicy::GetName() const { + return component_name_; +} + +update_client::InstallerAttributes +HTTPSEverywhereComponentInstallerPolicy::GetInstallerAttributes() const { + return update_client::InstallerAttributes(); +} + +void OnRegistered() { + BraveOnDemandUpdater::GetInstance()->OnDemandUpdate( + kHTTPSEverywhereComponentId); +} + +} // namespace + +// static +void SetHTTPSEverywhereComponentIdAndBase64PublicKeyForTest( + const std::string& component_id, + const std::string& component_base64_public_key) { + *HTTPSEverywhereComponentInstallerPolicy::g_https_everywhere_component_id_ = + component_id; + *HTTPSEverywhereComponentInstallerPolicy:: + g_https_everywhere_component_base64_public_key_ = + component_base64_public_key; +} + +void RegisterHTTPSEverywhereComponent( + component_updater::ComponentUpdateService* cus) { + // In test, |cus| could be nullptr. + if (!cus) + return; + + auto installer = base::MakeRefCounted( + std::make_unique()); + installer->Register(cus, base::BindOnce(&OnRegistered)); +} + +} // namespace brave_shields diff --git a/browser/brave_shields/https_everywhere_component_installer.h b/browser/brave_shields/https_everywhere_component_installer.h new file mode 100644 index 000000000000..fd9c471342b1 --- /dev/null +++ b/browser/brave_shields/https_everywhere_component_installer.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_BRAVE_SHIELDS_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ +#define BRAVE_BROWSER_BRAVE_SHIELDS_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ + +#include + +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater + +namespace brave_shields { + +void SetHTTPSEverywhereComponentIdAndBase64PublicKeyForTest( + const std::string& component_id, + const std::string& component_base64_public_key); + +void RegisterHTTPSEverywhereComponent( + component_updater::ComponentUpdateService* cus); + +} // namespace brave_shields + +#endif // BRAVE_BROWSER_BRAVE_SHIELDS_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ diff --git a/browser/brave_shields/sources.gni b/browser/brave_shields/sources.gni index 7f095d304c07..67d0def2f896 100644 --- a/browser/brave_shields/sources.gni +++ b/browser/brave_shields/sources.gni @@ -14,6 +14,8 @@ brave_browser_brave_shields_sources = [ "//brave/browser/brave_shields/brave_shields_web_contents_observer.h", "//brave/browser/brave_shields/cookie_pref_service_factory.cc", "//brave/browser/brave_shields/cookie_pref_service_factory.h", + "//brave/browser/brave_shields/https_everywhere_component_installer.cc", + "//brave/browser/brave_shields/https_everywhere_component_installer.h", ] brave_browser_brave_shields_deps = [ diff --git a/browser/ephemeral_storage/ephemeral_storage_1p_domain_block_browsertest.cc b/browser/ephemeral_storage/ephemeral_storage_1p_domain_block_browsertest.cc index ea899c2f9b75..7b4f24d8ee1d 100644 --- a/browser/ephemeral_storage/ephemeral_storage_1p_domain_block_browsertest.cc +++ b/browser/ephemeral_storage/ephemeral_storage_1p_domain_block_browsertest.cc @@ -12,6 +12,7 @@ #include "brave/components/brave_component_updater/browser/local_data_files_service.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" +#include "brave/components/brave_shields/browser/test_filters_provider.h" #include "brave/components/brave_shields/common/features.h" #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" #include "chrome/browser/profiles/profile.h" @@ -45,12 +46,13 @@ class EphemeralStorage1pDomainBlockBrowserTest void UpdateAdBlockInstanceWithRules(const std::string& rules, const std::string& resources = "") { + source_provider_ = + std::make_unique(rules, resources); + brave_shields::AdBlockService* ad_block_service = g_brave_browser_process->ad_block_service(); - ad_block_service->GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&brave_shields::AdBlockService::ResetForTest, - base::Unretained(ad_block_service), rules, resources)); + ad_block_service->UseSourceProvidersForTest(source_provider_.get(), + source_provider_.get()); WaitForAdBlockServiceThreads(); } @@ -160,6 +162,7 @@ class EphemeralStorage1pDomainBlockBrowserTest } protected: + std::unique_ptr source_provider_; base::test::ScopedFeatureList scoped_feature_list_; GURL a_site_simple_url_; GURL b_site_simple_url_; diff --git a/browser/extensions/api/brave_shields_api.cc b/browser/extensions/api/brave_shields_api.cc index cf7000f6f466..f4238d19e45a 100644 --- a/browser/extensions/api/brave_shields_api.cc +++ b/browser/extensions/api/brave_shields_api.cc @@ -14,7 +14,7 @@ #include "brave/browser/ui/brave_pages.h" #include "brave/browser/webcompat_reporter/webcompat_reporter_dialog.h" #include "brave/common/extensions/api/brave_shields.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/brave_shields_p3a.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" @@ -51,12 +51,12 @@ BraveShieldsAddSiteCosmeticFilterFunction::Run() { brave_shields::AddSiteCosmeticFilter::Params::Create(args())); EXTENSION_FUNCTION_VALIDATE(params.get()); - auto* custom_filters_service = - g_brave_browser_process->ad_block_custom_filters_service(); - std::string custom_filters = custom_filters_service->GetCustomFilters(); - custom_filters_service->UpdateCustomFilters(custom_filters + '\n' + - params->host + "##" + - params->css_selector + '\n'); + auto* custom_filters_provider = + g_brave_browser_process->ad_block_service()->custom_filters_provider(); + std::string custom_filters = custom_filters_provider->GetCustomFilters(); + custom_filters_provider->UpdateCustomFilters(custom_filters + '\n' + + params->host + "##" + + params->css_selector + '\n'); return RespondNow(NoArguments()); } diff --git a/browser/net/brave_ad_block_csp_network_delegate_helper.cc b/browser/net/brave_ad_block_csp_network_delegate_helper.cc index 1b26e19f7245..160723243838 100644 --- a/browser/net/brave_ad_block_csp_network_delegate_helper.cc +++ b/browser/net/brave_ad_block_csp_network_delegate_helper.cc @@ -77,9 +77,6 @@ int OnHeadersReceived_AdBlockCspWork( new net::HttpResponseHeaders(response_headers->raw_headers()); } - scoped_refptr task_runner = - g_brave_browser_process->ad_block_service()->GetTaskRunner(); - std::string original_csp_string; absl::optional original_csp = absl::nullopt; if ((*override_response_headers) @@ -90,11 +87,13 @@ int OnHeadersReceived_AdBlockCspWork( (*override_response_headers)->RemoveHeader("Content-Security-Policy"); - task_runner->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&GetCspDirectivesOnTaskRunner, ctx, original_csp), - base::BindOnce(&OnReceiveCspDirectives, next_callback, ctx, - *override_response_headers)); + g_brave_browser_process->ad_block_service() + ->GetTaskRunner() + ->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetCspDirectivesOnTaskRunner, ctx, original_csp), + base::BindOnce(&OnReceiveCspDirectives, next_callback, ctx, + *override_response_headers)); return net::ERR_IO_PENDING; } diff --git a/browser/net/brave_ad_block_tp_network_delegate_helper_unittest.cc b/browser/net/brave_ad_block_tp_network_delegate_helper_unittest.cc index 9c158cef99f8..f0a21b60647d 100644 --- a/browser/net/brave_ad_block_tp_network_delegate_helper_unittest.cc +++ b/browser/net/brave_ad_block_tp_network_delegate_helper_unittest.cc @@ -18,6 +18,7 @@ #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_subscription_download_manager.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h" +#include "brave/components/brave_shields/browser/test_filters_provider.h" #include "brave/test/base/testing_brave_browser_process.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/common/chrome_paths.h" @@ -31,6 +32,7 @@ #include "testing/gtest/include/gtest/gtest.h" using brave::ResponseCallback; +using brave_shields::TestFiltersProvider; namespace { @@ -95,9 +97,12 @@ class BraveAdBlockTPNetworkDelegateHelperTest : public testing::Test { base::FilePath user_data_dir; DCHECK(base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); auto adblock_service = std::make_unique( - brave_component_updater_delegate_.get(), + brave_component_updater_delegate_->local_state(), + brave_component_updater_delegate_->locale(), nullptr, + brave_component_updater_delegate_->GetTaskRunner(), std::make_unique( - brave_component_updater_delegate_.get(), + brave_component_updater_delegate_->local_state(), + brave_component_updater_delegate_->GetTaskRunner(), base::BindOnce(&FakeAdBlockSubscriptionDownloadManagerGetter), user_data_dir)); @@ -123,10 +128,10 @@ class BraveAdBlockTPNetworkDelegateHelperTest : public testing::Test { TestingBraveBrowserProcess::DeleteInstance(); } - void ResetAdblockInstance(brave_shields::AdBlockBaseService* service, - std::string rules, - std::string resources) { - service->ResetForTest(rules, resources); + void ResetAdblockInstance(std::string rules, std::string resources) { + filters_provider_ = std::make_unique(rules, resources); + g_brave_browser_process->ad_block_service()->UseSourceProvidersForTest( + filters_provider_.get(), filters_provider_.get()); } // Returns true if the request handler deferred control back to the calling @@ -154,6 +159,8 @@ class BraveAdBlockTPNetworkDelegateHelperTest : public testing::Test { std::unique_ptr stub_resolver_config_reader_; + std::unique_ptr filters_provider_; + private: std::unique_ptr resolver_wrapper_; }; @@ -204,8 +211,7 @@ TEST_F(BraveAdBlockTPNetworkDelegateHelperTest, RequestDataURL) { } TEST_F(BraveAdBlockTPNetworkDelegateHelperTest, SimpleBlocking) { - ResetAdblockInstance(g_brave_browser_process->ad_block_service(), - "||brave.com/test.txt", ""); + ResetAdblockInstance("||brave.com/test.txt", ""); const GURL url("https://brave.com/test.txt"); auto request_info = std::make_shared(url); diff --git a/browser/net/brave_httpse_network_delegate_helper.cc b/browser/net/brave_httpse_network_delegate_helper.cc index 2a5a7b7ed6f8..ca81d4baaabf 100644 --- a/browser/net/brave_httpse_network_delegate_helper.cc +++ b/browser/net/brave_httpse_network_delegate_helper.cc @@ -23,12 +23,15 @@ using content::BrowserThread; namespace brave { -void OnBeforeURLRequest_HttpseFileWork(std::shared_ptr ctx) { +void OnBeforeURLRequest_HttpseFileWork( + base::WeakPtr engine, + std::shared_ptr ctx) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::WILL_BLOCK); DCHECK_NE(ctx->request_identifier, 0U); - g_brave_browser_process->https_everywhere_service()->GetHTTPSURL( - &ctx->request_url, ctx->request_identifier, &ctx->new_url_spec); + if (engine) + engine->GetHTTPSURL(&ctx->request_url, ctx->request_identifier, + &ctx->new_url_spec); } void OnBeforeURLRequest_HttpsePostFileWork( @@ -79,7 +82,11 @@ int OnBeforeURLRequest_HttpsePreFileWork( g_brave_browser_process->https_everywhere_service() ->GetTaskRunner() ->PostTaskAndReply( - FROM_HERE, base::BindOnce(OnBeforeURLRequest_HttpseFileWork, ctx), + FROM_HERE, + base::BindOnce( + OnBeforeURLRequest_HttpseFileWork, + g_brave_browser_process->https_everywhere_service()->engine(), + ctx), base::BindOnce( base::IgnoreResult(&OnBeforeURLRequest_HttpsePostFileWork), next_callback, ctx)); diff --git a/browser/ui/webui/brave_adblock_ui.cc b/browser/ui/webui/brave_adblock_ui.cc index ba46fbd4e1b7..479ab59867a1 100644 --- a/browser/ui/webui/brave_adblock_ui.cc +++ b/browser/ui/webui/brave_adblock_ui.cc @@ -14,7 +14,7 @@ #include "brave/browser/ui/webui/brave_webui_source.h" #include "brave/common/webui_url_constants.h" #include "brave/components/brave_adblock/resources/grit/brave_adblock_generated_map.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" #include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_service_helper.h" @@ -143,7 +143,8 @@ void AdblockDOMHandler::HandleEnableFilterList( std::string uuid = args[0].GetString(); bool enabled = args[1].GetBool(); - g_brave_browser_process->ad_block_regional_service_manager() + g_brave_browser_process->ad_block_service() + ->regional_service_manager() ->EnableFilterList(uuid, enabled); } @@ -151,9 +152,9 @@ void AdblockDOMHandler::HandleGetCustomFilters( base::Value::ConstListView args) { DCHECK_EQ(args.size(), 0U); AllowJavascript(); - const std::string custom_filters = - g_brave_browser_process->ad_block_custom_filters_service() - ->GetCustomFilters(); + const std::string custom_filters = g_brave_browser_process->ad_block_service() + ->custom_filters_provider() + ->GetCustomFilters(); CallJavascriptFunction("brave_adblock.onGetCustomFilters", base::Value(custom_filters)); } @@ -163,7 +164,8 @@ void AdblockDOMHandler::HandleGetRegionalLists( DCHECK_EQ(args.size(), 0U); AllowJavascript(); std::unique_ptr regional_lists = - g_brave_browser_process->ad_block_regional_service_manager() + g_brave_browser_process->ad_block_service() + ->regional_service_manager() ->GetRegionalLists(); CallJavascriptFunction("brave_adblock.onGetRegionalLists", *regional_lists); } @@ -182,7 +184,8 @@ void AdblockDOMHandler::HandleUpdateCustomFilters( return; std::string custom_filters = args[0].GetString(); - g_brave_browser_process->ad_block_custom_filters_service() + g_brave_browser_process->ad_block_service() + ->custom_filters_provider() ->UpdateCustomFilters(custom_filters); } diff --git a/chromium_src/chrome/browser/component_updater/registration.cc b/chromium_src/chrome/browser/component_updater/registration.cc index a0a5dbdc9cc6..e902949440bf 100644 --- a/chromium_src/chrome/browser/component_updater/registration.cc +++ b/chromium_src/chrome/browser/component_updater/registration.cc @@ -9,8 +9,9 @@ #include "src/chrome/browser/component_updater/registration.cc" #undef RegisterComponentsForUpdate -#include "chrome/browser/browser_process.h" +#include "brave/browser/brave_shields/https_everywhere_component_installer.h" #include "brave/components/brave_wallet/browser/wallet_data_files_installer.h" +#include "chrome/browser/browser_process.h" namespace component_updater { @@ -18,6 +19,7 @@ void RegisterComponentsForUpdate() { RegisterComponentsForUpdate_ChromiumImpl(); ComponentUpdateService* cus = g_browser_process->component_updater(); brave_wallet::RegisterWalletDataFilesComponent(cus); + brave_shields::RegisterHTTPSEverywhereComponent(cus); } } // namespace component_updater diff --git a/components/brave_component_updater/browser/dat_file_util.cc b/components/brave_component_updater/browser/dat_file_util.cc index ea142ea3212b..9376d9db8850 100644 --- a/components/brave_component_updater/browser/dat_file_util.cc +++ b/components/brave_component_updater/browser/dat_file_util.cc @@ -5,16 +5,17 @@ #include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include #include #include "base/logging.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -namespace brave_component_updater { +namespace { void GetDATFileData(const base::FilePath& file_path, - DATFileDataBuffer* buffer) { + brave_component_updater::DATFileDataBuffer* buffer) { int64_t size = 0; if (!base::PathExists(file_path) || !base::GetFileSize(file_path, &size) || @@ -34,6 +35,16 @@ void GetDATFileData(const base::FilePath& file_path, } } +} // namespace + +namespace brave_component_updater { + +DATFileDataBuffer ReadDATFileData(const base::FilePath& dat_file_path) { + DATFileDataBuffer buffer; + GetDATFileData(dat_file_path, &buffer); + return buffer; +} + std::string GetDATFileAsString(const base::FilePath& file_path) { std::string contents; bool success = base::ReadFileToString(file_path, &contents); diff --git a/components/brave_component_updater/browser/dat_file_util.h b/components/brave_component_updater/browser/dat_file_util.h index 2c0a2c7c8700..164ae9b8ce66 100644 --- a/components/brave_component_updater/browser/dat_file_util.h +++ b/components/brave_component_updater/browser/dat_file_util.h @@ -17,17 +17,17 @@ namespace brave_component_updater { using DATFileDataBuffer = std::vector; -void GetDATFileData(const base::FilePath& file_path, DATFileDataBuffer* buffer); std::string GetDATFileAsString(const base::FilePath& file_path); +DATFileDataBuffer ReadDATFileData(const base::FilePath& dat_file_path); + template using LoadDATFileDataResult = std::pair, brave_component_updater::DATFileDataBuffer>; template LoadDATFileDataResult LoadDATFileData(const base::FilePath& dat_file_path) { - DATFileDataBuffer buffer; - GetDATFileData(dat_file_path, &buffer); + DATFileDataBuffer buffer = ReadDATFileData(dat_file_path); std::unique_ptr client; client = std::make_unique(); if (buffer.empty() || @@ -39,8 +39,7 @@ LoadDATFileDataResult LoadDATFileData(const base::FilePath& dat_file_path) { template LoadDATFileDataResult LoadRawFileData(const base::FilePath& dat_file_path) { - DATFileDataBuffer buffer; - GetDATFileData(dat_file_path, &buffer); + DATFileDataBuffer buffer = ReadDATFileData(dat_file_path); std::unique_ptr client; if (!buffer.empty()) diff --git a/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts b/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts index 9e7f70b95068..4dcf26b952cf 100644 --- a/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts +++ b/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts @@ -108,9 +108,6 @@ export default function shieldsPanelReducer ( // and used interchangably and all this code will be removed soon. state = shieldsPanelState.updateTabShieldsData(state, action.details.id, action.details) shieldsPanelState.updateShieldsIcon(state) - if (chrome.test && shieldsPanelState.getActiveTabData(state)) { - chrome.test.sendMessage('brave-extension-shields-data-ready') - } break } case shieldsPanelTypes.SHIELDS_TOGGLED: { diff --git a/components/brave_perf_predictor/browser/perf_predictor_tab_helper_browsertest.cc b/components/brave_perf_predictor/browser/perf_predictor_tab_helper_browsertest.cc index 8c3bf6a4f0bf..be18323f629f 100644 --- a/components/brave_perf_predictor/browser/perf_predictor_tab_helper_browsertest.cc +++ b/components/brave_perf_predictor/browser/perf_predictor_tab_helper_browsertest.cc @@ -11,8 +11,8 @@ #include "brave/common/pref_names.h" #include "brave/components/brave_component_updater/browser/local_data_files_service.h" #include "brave/components/brave_perf_predictor/common/pref_names.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" #include "brave/components/brave_shields/browser/ad_block_service.h" +#include "brave/components/brave_shields/browser/test_filters_provider.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" @@ -39,6 +39,8 @@ uint64_t getProfileAdsBlocked(Browser* browser) { } // namespace +using brave_shields::TestFiltersProvider; + class PerfPredictorTabHelperTest : public InProcessBrowserTest { public: PerfPredictorTabHelperTest() {} @@ -55,8 +57,6 @@ class PerfPredictorTabHelperTest : public InProcessBrowserTest { void PreRunTestOnMainThread() override { InProcessBrowserTest::PreRunTestOnMainThread(); - // Need ad_block_service to be available to get blocking savings predictions - ASSERT_TRUE(g_brave_browser_process->ad_block_service()->IsInitialized()); } void TearDown() override { InProcessBrowserTest::TearDown(); } @@ -71,21 +71,24 @@ class PerfPredictorTabHelperTest : public InProcessBrowserTest { } void UpdateAdBlockInstanceWithRules(const std::string& rules) { + filters_provider_ = std::make_unique(rules, ""); + brave_shields::AdBlockService* ad_block_service = g_brave_browser_process->ad_block_service(); - ad_block_service->GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&brave_shields::AdBlockService::ResetForTest, - base::Unretained(ad_block_service), rules, "")); + + ad_block_service->UseSourceProvidersForTest(filters_provider_.get(), + filters_provider_.get()); WaitForAdBlockServiceThreads(); } void WaitForAdBlockServiceThreads() { scoped_refptr tr_helper(new base::ThreadTestHelper( - g_brave_browser_process->local_data_files_service()->GetTaskRunner())); + g_brave_browser_process->ad_block_service()->GetTaskRunner())); ASSERT_TRUE(tr_helper->Run()); } + + std::unique_ptr filters_provider_; }; IN_PROC_BROWSER_TEST_F(PerfPredictorTabHelperTest, NoBlockNoSavings) { diff --git a/components/brave_shields/browser/BUILD.gn b/components/brave_shields/browser/BUILD.gn index 9b82030b27f6..3ce8bbdf90bd 100644 --- a/components/brave_shields/browser/BUILD.gn +++ b/components/brave_shields/browser/BUILD.gn @@ -1,15 +1,25 @@ static_library("browser") { sources = [ - "ad_block_base_service.cc", - "ad_block_base_service.h", - "ad_block_custom_filters_service.cc", - "ad_block_custom_filters_service.h", + "ad_block_component_installer.cc", + "ad_block_component_installer.h", + "ad_block_custom_filters_provider.cc", + "ad_block_custom_filters_provider.h", + "ad_block_default_filters_provider.cc", + "ad_block_default_filters_provider.h", + "ad_block_engine.cc", + "ad_block_engine.h", + "ad_block_filters_provider.cc", + "ad_block_filters_provider.h", "ad_block_pref_service.cc", "ad_block_pref_service.h", - "ad_block_regional_service.cc", - "ad_block_regional_service.h", + "ad_block_regional_catalog_provider.cc", + "ad_block_regional_catalog_provider.h", + "ad_block_regional_filters_provider.cc", + "ad_block_regional_filters_provider.h", "ad_block_regional_service_manager.cc", "ad_block_regional_service_manager.h", + "ad_block_resource_provider.cc", + "ad_block_resource_provider.h", "ad_block_service.cc", "ad_block_service.h", "ad_block_service_helper.cc", @@ -18,8 +28,8 @@ static_library("browser") { "ad_block_subscription_download_client.h", "ad_block_subscription_download_manager.cc", "ad_block_subscription_download_manager.h", - "ad_block_subscription_service.cc", - "ad_block_subscription_service.h", + "ad_block_subscription_filters_provider.cc", + "ad_block_subscription_filters_provider.h", "ad_block_subscription_service_manager.cc", "ad_block_subscription_service_manager.h", "ad_block_subscription_service_manager_observer.h", diff --git a/components/brave_shields/browser/ad_block_component_installer.cc b/components/brave_shields/browser/ad_block_component_installer.cc new file mode 100644 index 000000000000..1fa9359d8f6d --- /dev/null +++ b/components/brave_shields/browser/ad_block_component_installer.cc @@ -0,0 +1,190 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_component_installer.h" + +#include +#include +#include + +#include "base/base64.h" +#include "base/bind.h" +#include "base/callback.h" +#include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h" +#include "components/component_updater/component_installer.h" +#include "components/component_updater/component_updater_service.h" +#include "crypto/sha2.h" + +using brave_component_updater::BraveOnDemandUpdater; + +namespace brave_shields { + +namespace { + +constexpr size_t kHashSize = 32; +const char kAdBlockComponentName[] = "Brave Ad Block Updater"; +const char kAdBlockComponentId[] = "cffkpbalmllkdoenhmdmpbkajipdjfam"; +const char kAdBlockComponentBase64PublicKey[] = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0qzJmHSgIiw7IGFCxij" + "1NnB5hJ5ZQ1LKW9htL4EBOaMJvmqaDs/wfq0nw/goBHWsqqkMBynRTu2Hxxirvdb" + "cugn1Goys5QKPgAvKwDHJp9jlnADWm5xQvPQ4GE1mK1/I3ka9cEOCzPW6GI+wGLi" + "VPx9VZrxHHsSBIJRaEB5Tyi5bj0CZ+kcfMnRTsXIBw3C6xJgCVKISQUkd8mawVvG" + "vqOhBOogCdb9qza5eJ1Cgx8RWKucFfaWWxKLOelCiBMT1Hm1znAoVBHG/blhJJOD" + "5HcH/heRrB4MvrE1J76WF3fvZ03aHVcnlLtQeiNNOZ7VbBDXdie8Nomf/QswbBGa" + "VwIDAQAB"; + +std::string g_ad_block_component_id_(kAdBlockComponentId); +std::string g_ad_block_component_base64_public_key_( + kAdBlockComponentBase64PublicKey); + +class AdBlockComponentInstallerPolicy + : public component_updater::ComponentInstallerPolicy { + public: + explicit AdBlockComponentInstallerPolicy( + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback); + ~AdBlockComponentInstallerPolicy() override; + + AdBlockComponentInstallerPolicy(const AdBlockComponentInstallerPolicy&) = + delete; + AdBlockComponentInstallerPolicy& operator=( + const AdBlockComponentInstallerPolicy&) = delete; + + // component_updater::ComponentInstallerPolicy + bool SupportsGroupPolicyEnabledComponentUpdates() const override; + bool RequiresNetworkEncryption() const override; + update_client::CrxInstaller::Result OnCustomInstall( + const base::Value& manifest, + const base::FilePath& install_dir) override; + void OnCustomUninstall() override; + bool VerifyInstallation(const base::Value& manifest, + const base::FilePath& install_dir) const override; + void ComponentReady(const base::Version& version, + const base::FilePath& path, + base::Value manifest) override; + base::FilePath GetRelativeInstallDir() const override; + void GetHash(std::vector* hash) const override; + std::string GetName() const override; + update_client::InstallerAttributes GetInstallerAttributes() const override; + + private: + const std::string component_id_; + const std::string component_name_; + OnComponentReadyCallback ready_callback_; + uint8_t component_hash_[kHashSize]; +}; + +AdBlockComponentInstallerPolicy::AdBlockComponentInstallerPolicy( + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback) + : component_id_(component_id), + component_name_(component_name), + ready_callback_(callback) { + // Generate hash from public key. + std::string decoded_public_key; + base::Base64Decode(component_public_key, &decoded_public_key); + crypto::SHA256HashString(decoded_public_key, component_hash_, kHashSize); +} + +AdBlockComponentInstallerPolicy::~AdBlockComponentInstallerPolicy() = default; + +bool AdBlockComponentInstallerPolicy:: + SupportsGroupPolicyEnabledComponentUpdates() const { + return true; +} + +bool AdBlockComponentInstallerPolicy::RequiresNetworkEncryption() const { + return false; +} + +update_client::CrxInstaller::Result +AdBlockComponentInstallerPolicy::OnCustomInstall( + const base::Value& manifest, + const base::FilePath& install_dir) { + return update_client::CrxInstaller::Result(0); +} + +void AdBlockComponentInstallerPolicy::OnCustomUninstall() {} + +void AdBlockComponentInstallerPolicy::ComponentReady( + const base::Version& version, + const base::FilePath& path, + base::Value manifest) { + ready_callback_.Run(path); +} + +bool AdBlockComponentInstallerPolicy::VerifyInstallation( + const base::Value& manifest, + const base::FilePath& install_dir) const { + return true; +} + +base::FilePath AdBlockComponentInstallerPolicy::GetRelativeInstallDir() const { + return base::FilePath::FromUTF8Unsafe(component_id_); +} + +void AdBlockComponentInstallerPolicy::GetHash( + std::vector* hash) const { + hash->assign(component_hash_, component_hash_ + kHashSize); +} + +std::string AdBlockComponentInstallerPolicy::GetName() const { + return component_name_; +} + +update_client::InstallerAttributes +AdBlockComponentInstallerPolicy::GetInstallerAttributes() const { + return update_client::InstallerAttributes(); +} + +void OnRegistered(const std::string& component_id) { + BraveOnDemandUpdater::GetInstance()->OnDemandUpdate(component_id); +} + +} // namespace + +void RegisterAdBlockDefaultComponent( + component_updater::ComponentUpdateService* cus, + OnComponentReadyCallback callback) { + // In test, |cus| could be nullptr. + if (!cus) + return; + + auto installer = base::MakeRefCounted( + std::make_unique( + g_ad_block_component_base64_public_key_, g_ad_block_component_id_, + kAdBlockComponentName, callback)); + installer->Register(cus, base::BindOnce(&OnRegistered, kAdBlockComponentId)); +} + +void RegisterAdBlockRegionalComponent( + component_updater::ComponentUpdateService* cus, + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback) { + // In test, |cus| could be nullptr. + if (!cus) + return; + + auto installer = base::MakeRefCounted( + std::make_unique( + component_public_key, component_id, component_name, callback)); + installer->Register(cus, base::BindOnce(&OnRegistered, component_id)); +} + +// static +void SetDefaultAdBlockComponentIdAndBase64PublicKeyForTest( + const std::string& component_id, + const std::string& component_base64_public_key) { + g_ad_block_component_id_ = component_id; + g_ad_block_component_base64_public_key_ = component_base64_public_key; +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_component_installer.h b/components/brave_shields/browser/ad_block_component_installer.h new file mode 100644 index 000000000000..3e3c578cdd5d --- /dev/null +++ b/components/brave_shields/browser/ad_block_component_installer.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_COMPONENT_INSTALLER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_COMPONENT_INSTALLER_H_ + +#include + +#include "base/callback.h" +#include "base/files/file_path.h" + +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater + +namespace brave_shields { + +// static +void SetDefaultAdBlockComponentIdAndBase64PublicKeyForTest( + const std::string& component_id, + const std::string& component_base64_public_key); + +using OnComponentReadyCallback = + base::RepeatingCallback; + +void RegisterAdBlockDefaultComponent( + component_updater::ComponentUpdateService* cus, + OnComponentReadyCallback callback); + +void RegisterAdBlockRegionalComponent( + component_updater::ComponentUpdateService* cus, + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback); + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_COMPONENT_INSTALLER_H_ diff --git a/components/brave_shields/browser/ad_block_custom_filters_provider.cc b/components/brave_shields/browser/ad_block_custom_filters_provider.cc new file mode 100644 index 000000000000..020aeb8ce8fd --- /dev/null +++ b/components/brave_shields/browser/ad_block_custom_filters_provider.cc @@ -0,0 +1,58 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" + +#include +#include + +#include "base/threading/thread_task_runner_handle.h" +#include "brave/components/brave_shields/common/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace brave_shields { + +AdBlockCustomFiltersProvider::AdBlockCustomFiltersProvider( + PrefService* local_state) + : local_state_(local_state) {} + +AdBlockCustomFiltersProvider::~AdBlockCustomFiltersProvider() {} + +std::string AdBlockCustomFiltersProvider::GetCustomFilters() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!local_state_) + return std::string(); + return local_state_->GetString(prefs::kAdBlockCustomFilters); +} + +bool AdBlockCustomFiltersProvider::UpdateCustomFilters( + const std::string& custom_filters) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!local_state_) + return false; + local_state_->SetString(prefs::kAdBlockCustomFilters, custom_filters); + + auto buffer = + std::vector(custom_filters.begin(), custom_filters.end()); + OnDATLoaded(false, buffer); + + return true; +} + +void AdBlockCustomFiltersProvider::LoadDATBuffer( + base::OnceCallback + cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto custom_filters = GetCustomFilters(); + + auto buffer = + std::vector(custom_filters.begin(), custom_filters.end()); + + // PostTask so this has an async return to match other loaders + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(cb), false, std::move(buffer))); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_custom_filters_provider.h b/components/brave_shields/browser/ad_block_custom_filters_provider.h new file mode 100644 index 000000000000..b8fe59176a21 --- /dev/null +++ b/components/brave_shields/browser/ad_block_custom_filters_provider.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_PROVIDER_H_ + +#include + +#include "base/callback.h" +#include "base/sequence_checker.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" + +using brave_component_updater::DATFileDataBuffer; + +class PrefService; + +namespace brave_shields { + +class AdBlockCustomFiltersProvider : public AdBlockFiltersProvider { + public: + explicit AdBlockCustomFiltersProvider(PrefService* local_state); + ~AdBlockCustomFiltersProvider() override; + AdBlockCustomFiltersProvider(const AdBlockCustomFiltersProvider&) = delete; + AdBlockCustomFiltersProvider& operator=(const AdBlockCustomFiltersProvider&) = + delete; + + std::string GetCustomFilters(); + bool UpdateCustomFilters(const std::string& custom_filters); + + void LoadDATBuffer( + base::OnceCallback) override; + + private: + PrefService* local_state_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_custom_filters_service.cc b/components/brave_shields/browser/ad_block_custom_filters_service.cc deleted file mode 100644 index ac8b7f80a453..000000000000 --- a/components/brave_shields/browser/ad_block_custom_filters_service.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" - -#include "base/logging.h" -#include "brave/components/adblock_rust_ffi/src/wrapper.h" -#include "brave/components/brave_shields/browser/ad_block_service.h" -#include "brave/components/brave_shields/common/pref_names.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browser_thread.h" - -using brave_component_updater::BraveComponent; - -namespace brave_shields { - -AdBlockCustomFiltersService::AdBlockCustomFiltersService( - BraveComponent::Delegate* delegate) - : AdBlockBaseService(delegate) {} - -AdBlockCustomFiltersService::~AdBlockCustomFiltersService() {} - -bool AdBlockCustomFiltersService::Init() { - return UpdateCustomFilters(GetCustomFilters()); -} - -std::string AdBlockCustomFiltersService::GetCustomFilters() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PrefService* local_state = delegate()->local_state(); - if (!local_state) - return std::string(); - return local_state->GetString(prefs::kAdBlockCustomFilters); -} - -bool AdBlockCustomFiltersService::UpdateCustomFilters( - const std::string& custom_filters) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PrefService* local_state = delegate()->local_state(); - if (!local_state) - return false; - local_state->SetString(prefs::kAdBlockCustomFilters, custom_filters); - - GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce( - &AdBlockCustomFiltersService::UpdateCustomFiltersOnFileTaskRunner, - base::Unretained(this), custom_filters)); - - return true; -} - -void AdBlockCustomFiltersService::UpdateCustomFiltersOnFileTaskRunner( - const std::string& custom_filters) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); - ad_block_client_.reset(new adblock::Engine(custom_filters.c_str())); -} - -/////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr AdBlockCustomFiltersServiceFactory( - BraveComponent::Delegate* delegate) { - return std::make_unique(delegate); -} - -} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_custom_filters_service.h b/components/brave_shields/browser/ad_block_custom_filters_service.h deleted file mode 100644 index c130d336a9e8..000000000000 --- a/components/brave_shields/browser/ad_block_custom_filters_service.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_SERVICE_H_ -#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_SERVICE_H_ - -#include -#include -#include -#include - -#include "brave/components/brave_shields/browser/ad_block_base_service.h" - -class AdBlockServiceTest; - -using brave_component_updater::BraveComponent; - -namespace brave_shields { - -// The brave shields service in charge of custom filter ad-block -// checking and init. -class AdBlockCustomFiltersService : public AdBlockBaseService { - public: - explicit AdBlockCustomFiltersService(BraveComponent::Delegate* delegate); - AdBlockCustomFiltersService(const AdBlockCustomFiltersService&) = delete; - AdBlockCustomFiltersService& operator=(const AdBlockCustomFiltersService&) = - delete; - ~AdBlockCustomFiltersService() override; - - std::string GetCustomFilters(); - bool UpdateCustomFilters(const std::string& custom_filters); - - protected: - bool Init() override; - - private: - friend class ::AdBlockServiceTest; - void UpdateCustomFiltersOnFileTaskRunner(const std::string& custom_filters); -}; - -// Creates the AdBlockCustomFiltersService -std::unique_ptr -AdBlockCustomFiltersServiceFactory(BraveComponent::Delegate* delegate); - -} // namespace brave_shields - -#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_CUSTOM_FILTERS_SERVICE_H_ diff --git a/components/brave_shields/browser/ad_block_default_filters_provider.cc b/components/brave_shields/browser/ad_block_default_filters_provider.cc new file mode 100644 index 000000000000..a49d2b8ea4cc --- /dev/null +++ b/components/brave_shields/browser/ad_block_default_filters_provider.cc @@ -0,0 +1,113 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_default_filters_provider.h" + +#include +#include +#include + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/task/thread_pool.h" +#include "brave/components/brave_shields/browser/ad_block_component_installer.h" +#include "content/public/browser/browser_task_traits.h" + +#define DAT_FILE "rs-ABPFilterParserData.dat" +#define REGIONAL_CATALOG "regional_catalog.json" +const char kAdBlockResourcesFilename[] = "resources.json"; + +namespace brave_shields { + +AdBlockDefaultFiltersProvider::AdBlockDefaultFiltersProvider( + component_updater::ComponentUpdateService* cus) { + // Can be nullptr in unit tests + if (cus) { + RegisterAdBlockDefaultComponent( + cus, + base::BindRepeating(&AdBlockDefaultFiltersProvider::OnComponentReady, + weak_factory_.GetWeakPtr())); + } +} + +AdBlockDefaultFiltersProvider::~AdBlockDefaultFiltersProvider() {} + +void AdBlockDefaultFiltersProvider::OnComponentReady( + const base::FilePath& path) { + component_path_ = path; + + // Load the DAT (as a buffer) + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::ReadDATFileData, + component_path_.AppendASCII(DAT_FILE)), + base::BindOnce(&AdBlockDefaultFiltersProvider::OnDATLoaded, + weak_factory_.GetWeakPtr(), true)); + + // Load the resources (as a string) + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::GetDATFileAsString, + component_path_.AppendASCII(kAdBlockResourcesFilename)), + base::BindOnce(&AdBlockDefaultFiltersProvider::OnResourcesLoaded, + weak_factory_.GetWeakPtr())); + + // Load the regional catalog (as a string) + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::GetDATFileAsString, + component_path_.AppendASCII(REGIONAL_CATALOG)), + base::BindOnce(&AdBlockDefaultFiltersProvider::OnRegionalCatalogLoaded, + weak_factory_.GetWeakPtr())); +} + +void AdBlockDefaultFiltersProvider::LoadDATBuffer( + base::OnceCallback + cb) { + if (component_path_.empty()) { + // If the path is not ready yet, don't run the callback. An update should + // be pushed soon. + return; + } + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::ReadDATFileData, + component_path_.AppendASCII(DAT_FILE)), + base::BindOnce(std::move(cb), true)); +} + +void AdBlockDefaultFiltersProvider::LoadResources( + base::OnceCallback cb) { + if (component_path_.empty()) { + // If the path is not ready yet, run the callback with empty resources to + // avoid blocking filter data loads. + std::move(cb).Run("[]"); + return; + } + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::GetDATFileAsString, + component_path_.AppendASCII(kAdBlockResourcesFilename)), + std::move(cb)); +} + +void AdBlockDefaultFiltersProvider::LoadRegionalCatalog( + base::OnceCallback cb) { + if (component_path_.empty()) { + // If the path is not ready yet, don't run the callback. An update should be + // pushed soon. + return; + } + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::GetDATFileAsString, + component_path_.AppendASCII(REGIONAL_CATALOG)), + std::move(cb)); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_default_filters_provider.h b/components/brave_shields/browser/ad_block_default_filters_provider.h new file mode 100644 index 000000000000..84ea9cbfacf5 --- /dev/null +++ b/components/brave_shields/browser/ad_block_default_filters_provider.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_DEFAULT_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_DEFAULT_FILTERS_PROVIDER_H_ + +#include + +#include "base/callback.h" +#include "base/observer_list.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_regional_catalog_provider.h" +#include "brave/components/brave_shields/browser/ad_block_resource_provider.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using brave_component_updater::DATFileDataBuffer; + +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater + +namespace base { +class FilePath; +} + +class AdBlockServiceTest; + +namespace brave_shields { + +class AdBlockDefaultFiltersProvider : public AdBlockFiltersProvider, + public AdBlockResourceProvider, + public AdBlockRegionalCatalogProvider { + public: + explicit AdBlockDefaultFiltersProvider( + component_updater::ComponentUpdateService* cus); + ~AdBlockDefaultFiltersProvider() override; + AdBlockDefaultFiltersProvider(const AdBlockDefaultFiltersProvider&) = delete; + AdBlockDefaultFiltersProvider& operator=( + const AdBlockDefaultFiltersProvider&) = delete; + + void LoadDATBuffer( + base::OnceCallback) override; + + void LoadResources( + base::OnceCallback) override; + + void LoadRegionalCatalog( + base::OnceCallback) override; + + private: + friend class ::AdBlockServiceTest; + void OnComponentReady(const base::FilePath&); + + base::FilePath component_path_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_DEFAULT_FILTERS_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_base_service.cc b/components/brave_shields/browser/ad_block_engine.cc similarity index 55% rename from components/brave_shields/browser/ad_block_base_service.cc rename to components/brave_shields/browser/ad_block_engine.cc index b76702763d33..c1e554ecceb8 100644 --- a/components/brave_shields/browser/ad_block_base_service.cc +++ b/components/brave_shields/browser/ad_block_engine.cc @@ -1,9 +1,9 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. +/* Copyright (c) 2021 The Brave Authors. All rights reserved. * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "brave/components/brave_shields/browser/ad_block_base_service.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" #include #include @@ -16,19 +16,13 @@ #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/task/thread_pool.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" #include "brave/components/brave_component_updater/browser/dat_file_util.h" #include "brave/components/brave_shields/common/brave_shield_constants.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/origin.h" -using brave_component_updater::BraveComponent; -using content::BrowserThread; using namespace net::registry_controlled_domains; // NOLINT namespace { @@ -103,28 +97,18 @@ std::string ResourceTypeToString(blink::mojom::ResourceType resource_type) { namespace brave_shields { -AdBlockBaseService::AdBlockBaseService(BraveComponent::Delegate* delegate) - : BaseBraveShieldsService(delegate), - ad_block_client_(new adblock::Engine()), - weak_factory_(this) {} +AdBlockEngine::AdBlockEngine() : ad_block_client_(new adblock::Engine()) {} -AdBlockBaseService::~AdBlockBaseService() { - GetTaskRunner()->DeleteSoon(FROM_HERE, ad_block_client_.release()); -} - -void AdBlockBaseService::ShouldStartRequest( - const GURL& url, - blink::mojom::ResourceType resource_type, - const std::string& tab_host, - bool aggressive_blocking, - bool* did_match_rule, - bool* did_match_exception, - bool* did_match_important, - std::string* mock_data_url) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); - // if (!IsInitialized()) - // return; +AdBlockEngine::~AdBlockEngine() {} +void AdBlockEngine::ShouldStartRequest(const GURL& url, + blink::mojom::ResourceType resource_type, + const std::string& tab_host, + bool aggressive_blocking, + bool* did_match_rule, + bool* did_match_exception, + bool* did_match_important, + std::string* mock_data_url) { // Determine third-party here so the library doesn't need to figure it out. // CreateFromNormalizedTuple is needed because SameDomainOrHost needs // a URL or origin and not a string to a host name. @@ -137,18 +121,16 @@ void AdBlockBaseService::ShouldStartRequest( did_match_exception, did_match_important, mock_data_url); - // LOG(ERROR) << "AdBlockBaseService::ShouldStartRequest(), host: " + // LOG(ERROR) << "AdBlockEngine::ShouldStartRequest(), host: " // << tab_host // << ", resource type: " << resource_type // << ", url.spec(): " << url.spec(); } -absl::optional AdBlockBaseService::GetCspDirectives( +absl::optional AdBlockEngine::GetCspDirectives( const GURL& url, blink::mojom::ResourceType resource_type, const std::string& tab_host) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); - // Determine third-party here so the library doesn't need to figure it out. // CreateFromNormalizedTuple is needed because SameDomainOrHost needs // a URL or origin and not a string to a host name. @@ -167,14 +149,7 @@ absl::optional AdBlockBaseService::GetCspDirectives( } } -void AdBlockBaseService::EnableTag(const std::string& tag, bool enabled) { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&AdBlockBaseService::EnableTag, - base::Unretained(this), tag, enabled)); - return; - } - +void AdBlockEngine::EnableTag(const std::string& tag, bool enabled) { if (enabled) { if (tags_.find(tag) == tags_.end()) { ad_block_client_->addTag(tag); @@ -190,39 +165,23 @@ void AdBlockBaseService::EnableTag(const std::string& tag, bool enabled) { } } -void AdBlockBaseService::AddResources(const std::string& resources) { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&AdBlockBaseService::AddResources, - base::Unretained(this), resources)); - return; - } - +void AdBlockEngine::AddResources(const std::string& resources) { ad_block_client_->addResources(resources); - resources_ = resources; } -bool AdBlockBaseService::TagExists(const std::string& tag) { +bool AdBlockEngine::TagExists(const std::string& tag) { return std::find(tags_.begin(), tags_.end(), tag) != tags_.end(); } -absl::optional AdBlockBaseService::UrlCosmeticResources( +absl::optional AdBlockEngine::UrlCosmeticResources( const std::string& url) { - // if (!IsInitialized()) - // return; - - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); return base::JSONReader::Read(ad_block_client_->urlCosmeticResources(url)); } -base::Value AdBlockBaseService::HiddenClassIdSelectors( +base::Value AdBlockEngine::HiddenClassIdSelectors( const std::vector& classes, const std::vector& ids, const std::vector& exceptions) { - // if (!IsInitialized()) - // return; - - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); absl::optional result = base::JSONReader::Read( ad_block_client_->hiddenClassIdSelectors(classes, ids, exceptions)); @@ -233,73 +192,60 @@ base::Value AdBlockBaseService::HiddenClassIdSelectors( } } -void AdBlockBaseService::GetDATFileData(const base::FilePath& dat_file_path, - bool deserialize, - base::OnceClosure callback) { - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce( - deserialize - ? &brave_component_updater::LoadDATFileData - : &brave_component_updater::LoadRawFileData, - dat_file_path), - base::BindOnce(&AdBlockBaseService::OnGetDATFileData, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void AdBlockBaseService::OnGetDATFileData(base::OnceClosure callback, - GetDATFileDataResult result) { - if (result.second.empty()) { - LOG(ERROR) << "Could not obtain ad block data"; - return; - } - if (!result.first.get()) { - LOG(ERROR) << "Failed to deserialize ad block data"; - return; +void AdBlockEngine::Load(bool deserialize, + const DATFileDataBuffer& dat_buf, + const std::string& resources_json) { + if (deserialize) { + OnDATLoaded(dat_buf, resources_json); + } else { + OnListSourceLoaded(dat_buf, resources_json); } - GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&AdBlockBaseService::UpdateAdBlockClient, - base::Unretained(this), - std::move(result.first))); - // TODO(bridiver) this needs to happen after adblock client is actually reset - std::move(callback).Run(); } -void AdBlockBaseService::UpdateAdBlockClient( - std::unique_ptr ad_block_client) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); +void AdBlockEngine::UpdateAdBlockClient( + std::unique_ptr ad_block_client, + const std::string& resources_json) { ad_block_client_ = std::move(ad_block_client); + AddResources(resources_json); AddKnownTagsToAdBlockInstance(); - AddKnownResourcesToAdBlockInstance(); + if (test_observer_) { + test_observer_->OnEngineUpdated(); + } } -void AdBlockBaseService::AddKnownTagsToAdBlockInstance() { +void AdBlockEngine::AddKnownTagsToAdBlockInstance() { std::for_each(tags_.begin(), tags_.end(), [&](const std::string tag) { ad_block_client_->addTag(tag); }); } -void AdBlockBaseService::AddKnownResourcesToAdBlockInstance() { - ad_block_client_->addResources(resources_); +void AdBlockEngine::OnListSourceLoaded(const DATFileDataBuffer& filters, + const std::string& resources_json) { + UpdateAdBlockClient( + std::make_unique( + reinterpret_cast(filters.data()), filters.size()), + resources_json); } -bool AdBlockBaseService::Init() { - return true; +void AdBlockEngine::OnDATLoaded(const DATFileDataBuffer& dat_buf, + const std::string& resources_json) { + // An empty buffer will not load successfully. + if (dat_buf.empty()) { + return; + } + + auto client = std::make_unique(); + client->deserialize(reinterpret_cast(&dat_buf.front()), + dat_buf.size()); + + UpdateAdBlockClient(std::move(client), resources_json); } -void AdBlockBaseService::ResetForTest(const std::string& rules, - const std::string& resources) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); - // This is temporary until adblock-rust supports incrementally adding - // filter rules to an existing instance. At which point the hack below - // will dissapear. - ad_block_client_.reset(new adblock::Engine(rules)); - AddKnownTagsToAdBlockInstance(); - if (!resources.empty()) { - resources_ = resources; - } - AddKnownResourcesToAdBlockInstance(); +void AdBlockEngine::AddObserverForTest(AdBlockEngine::TestObserver* observer) { + test_observer_ = observer; } -/////////////////////////////////////////////////////////////////////////////// +void AdBlockEngine::RemoveObserverForTest() { + test_observer_ = nullptr; +} } // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_base_service.h b/components/brave_shields/browser/ad_block_engine.h similarity index 56% rename from components/brave_shields/browser/ad_block_base_service.h rename to components/brave_shields/browser/ad_block_engine.h index 569f5a6a3e9a..990fdd3ced74 100644 --- a/components/brave_shields/browser/ad_block_base_service.h +++ b/components/brave_shields/browser/ad_block_engine.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. +/* Copyright (c) 2021 The Brave Authors. All rights reserved. * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_BASE_SERVICE_H_ -#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_BASE_SERVICE_H_ +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_ENGINE_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_ENGINE_H_ #include @@ -14,37 +14,35 @@ #include #include -#include "base/files/file_path.h" #include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" #include "base/values.h" #include "brave/components/brave_component_updater/browser/dat_file_util.h" -#include "brave/components/brave_shields/browser/base_brave_shields_service.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" +#include "url/gurl.h" -class AdBlockServiceTest; -class BraveAdBlockTPNetworkDelegateHelperTest; -class EphemeralStorage1pDomainBlockBrowserTest; -class PerfPredictorTabHelperTest; +using brave_component_updater::DATFileDataBuffer; -using brave_component_updater::BraveComponent; namespace adblock { class Engine; } +class AdBlockServiceTest; +class BraveAdBlockTPNetworkDelegateHelperTest; +class EphemeralStorage1pDomainBlockBrowserTest; +class PerfPredictorTabHelperTest; + namespace brave_shields { -// The base class of the brave shields service in charge of ad-block -// checking and init. -class AdBlockBaseService : public BaseBraveShieldsService { +// Service managing an adblock engine. +class AdBlockEngine : public base::SupportsWeakPtr { public: using GetDATFileDataResult = brave_component_updater::LoadDATFileDataResult; - explicit AdBlockBaseService(BraveComponent::Delegate* delegate); - AdBlockBaseService(const AdBlockBaseService&) = delete; - AdBlockBaseService& operator=(const AdBlockBaseService&) = delete; - ~AdBlockBaseService() override; + AdBlockEngine(); + AdBlockEngine(const AdBlockEngine&) = delete; + AdBlockEngine& operator=(const AdBlockEngine&) = delete; + ~AdBlockEngine(); void ShouldStartRequest(const GURL& url, blink::mojom::ResourceType resource_type, @@ -53,7 +51,7 @@ class AdBlockBaseService : public BaseBraveShieldsService { bool* did_match_rule, bool* did_match_exception, bool* did_match_important, - std::string* mock_data_url) override; + std::string* mock_data_url); absl::optional GetCspDirectives( const GURL& url, blink::mojom::ResourceType resource_type, @@ -62,41 +60,47 @@ class AdBlockBaseService : public BaseBraveShieldsService { void EnableTag(const std::string& tag, bool enabled); bool TagExists(const std::string& tag); - virtual absl::optional UrlCosmeticResources( - const std::string& url); - virtual base::Value HiddenClassIdSelectors( + absl::optional UrlCosmeticResources(const std::string& url); + base::Value HiddenClassIdSelectors( const std::vector& classes, const std::vector& ids, const std::vector& exceptions); - protected: - friend class ::AdBlockServiceTest; - friend class ::BraveAdBlockTPNetworkDelegateHelperTest; - friend class ::EphemeralStorage1pDomainBlockBrowserTest; - friend class ::PerfPredictorTabHelperTest; + void Load(bool deserialize, + const DATFileDataBuffer& dat_buf, + const std::string& resources_json); - bool Init() override; + class TestObserver : public base::CheckedObserver { + public: + virtual void OnEngineUpdated() = 0; + }; - void GetDATFileData(const base::FilePath& dat_file_path, - bool deserialize = true, - base::OnceClosure callback = base::DoNothing()); + void AddObserverForTest(TestObserver* observer); + void RemoveObserverForTest(); + + protected: void AddKnownTagsToAdBlockInstance(); - void AddKnownResourcesToAdBlockInstance(); - void ResetForTest(const std::string& rules, const std::string& resources); + void UpdateAdBlockClient(std::unique_ptr ad_block_client, + const std::string& resources_json); + void OnListSourceLoaded(const DATFileDataBuffer& filters, + const std::string& resources_json); + + void OnDATLoaded(const DATFileDataBuffer& dat_buf, + const std::string& resources_json); std::unique_ptr ad_block_client_; private: - void UpdateAdBlockClient(std::unique_ptr ad_block_client); - void OnGetDATFileData(base::OnceClosure callback, - GetDATFileDataResult result); - void OnPreferenceChanges(const std::string& pref_name); + friend class ::AdBlockServiceTest; + friend class ::BraveAdBlockTPNetworkDelegateHelperTest; + friend class ::EphemeralStorage1pDomainBlockBrowserTest; + friend class ::PerfPredictorTabHelperTest; std::set tags_; - std::string resources_; - base::WeakPtrFactory weak_factory_; + + raw_ptr test_observer_ = nullptr; }; } // namespace brave_shields -#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_BASE_SERVICE_H_ +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_ENGINE_H_ diff --git a/components/brave_shields/browser/ad_block_filters_provider.cc b/components/brave_shields/browser/ad_block_filters_provider.cc new file mode 100644 index 000000000000..c21c5f292f9b --- /dev/null +++ b/components/brave_shields/browser/ad_block_filters_provider.cc @@ -0,0 +1,51 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" + +namespace brave_shields { + +AdBlockFiltersProvider::AdBlockFiltersProvider() {} + +AdBlockFiltersProvider::~AdBlockFiltersProvider() {} + +void AdBlockFiltersProvider::AddObserver( + AdBlockFiltersProvider::Observer* observer) { + if (!observers_.HasObserver(observer)) + observers_.AddObserver(observer); +} + +void AdBlockFiltersProvider::RemoveObserver( + AdBlockFiltersProvider::Observer* observer) { + if (observers_.HasObserver(observer)) + observers_.RemoveObserver(observer); +} + +void AdBlockFiltersProvider::OnDATLoaded(bool deserialize, + const DATFileDataBuffer& dat_buf) { + for (auto& observer : observers_) { + observer.OnDATLoaded(deserialize, dat_buf); + } +} + +void AdBlockFiltersProvider::LoadDAT( + AdBlockFiltersProvider::Observer* observer) { + LoadDATBuffer(base::BindOnce(&AdBlockFiltersProvider::OnLoad, + weak_factory_.GetWeakPtr(), observer)); +} + +void AdBlockFiltersProvider::OnLoad(AdBlockFiltersProvider::Observer* observer, + bool deserialize, + const DATFileDataBuffer& dat_buf) { + if (observers_.HasObserver(observer)) { + observer->OnDATLoaded(deserialize, dat_buf); + } +} + +bool AdBlockFiltersProvider::Delete() && { + return false; +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_filters_provider.h b/components/brave_shields/browser/ad_block_filters_provider.h new file mode 100644 index 000000000000..3e5a5cc94f5e --- /dev/null +++ b/components/brave_shields/browser/ad_block_filters_provider.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_FILTERS_PROVIDER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" + +using brave_component_updater::DATFileDataBuffer; + +namespace brave_shields { + +// Interface for any source that can load filters or serialized filter data +// into an adblock engine. +class AdBlockFiltersProvider { + public: + class Observer : public base::CheckedObserver { + public: + virtual void OnDATLoaded(bool deserialize, + const DATFileDataBuffer& dat_buf) = 0; + }; + + AdBlockFiltersProvider(); + AdBlockFiltersProvider(const AdBlockFiltersProvider&) = delete; + AdBlockFiltersProvider& operator=(const AdBlockFiltersProvider&) = delete; + virtual ~AdBlockFiltersProvider(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + void LoadDAT(Observer* observer); + + virtual bool Delete() &&; + + protected: + virtual void LoadDATBuffer( + base::OnceCallback) = 0; + + void OnLoad(AdBlockFiltersProvider::Observer* observer, + bool deserialize, + const DATFileDataBuffer& dat_buf); + void OnDATLoaded(bool deserialize, const DATFileDataBuffer& dat_buf); + + private: + base::ObserverList observers_; + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_FILTERS_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_pref_service.cc b/components/brave_shields/browser/ad_block_pref_service.cc index 8c787e1bf10c..29d0a0e59de5 100644 --- a/components/brave_shields/browser/ad_block_pref_service.cc +++ b/components/brave_shields/browser/ad_block_pref_service.cc @@ -6,7 +6,7 @@ #include "brave/components/brave_shields/browser/ad_block_pref_service.h" #include "base/bind.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" #include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h" diff --git a/components/brave_shields/browser/ad_block_regional_catalog_provider.cc b/components/brave_shields/browser/ad_block_regional_catalog_provider.cc new file mode 100644 index 000000000000..5565e0fb5c25 --- /dev/null +++ b/components/brave_shields/browser/ad_block_regional_catalog_provider.cc @@ -0,0 +1,33 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "brave/components/brave_shields/browser/ad_block_regional_catalog_provider.h" + +namespace brave_shields { + +AdBlockRegionalCatalogProvider::AdBlockRegionalCatalogProvider() {} + +AdBlockRegionalCatalogProvider::~AdBlockRegionalCatalogProvider() {} + +void AdBlockRegionalCatalogProvider::AddObserver( + AdBlockRegionalCatalogProvider::Observer* observer) { + observers_.AddObserver(observer); +} + +void AdBlockRegionalCatalogProvider::RemoveObserver( + AdBlockRegionalCatalogProvider::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void AdBlockRegionalCatalogProvider::OnRegionalCatalogLoaded( + const std::string& catalog_json) { + for (auto& observer : observers_) { + observer.OnRegionalCatalogLoaded(catalog_json); + } +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_regional_catalog_provider.h b/components/brave_shields/browser/ad_block_regional_catalog_provider.h new file mode 100644 index 000000000000..d88d5b88eab7 --- /dev/null +++ b/components/brave_shields/browser/ad_block_regional_catalog_provider.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_CATALOG_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_CATALOG_PROVIDER_H_ + +#include + +#include "base/callback.h" +#include "base/observer_list.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using brave_component_updater::DATFileDataBuffer; + +namespace brave_shields { + +class AdBlockRegionalCatalogProvider { + public: + class Observer : public base::CheckedObserver { + public: + virtual void OnRegionalCatalogLoaded(const std::string& catalog_json) = 0; + }; + + AdBlockRegionalCatalogProvider(); + virtual ~AdBlockRegionalCatalogProvider(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + virtual void LoadRegionalCatalog( + base::OnceCallback) = 0; + + protected: + void OnRegionalCatalogLoaded(const std::string& catalog_json); + + private: + base::ObserverList observers_; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_CATALOG_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_regional_filters_provider.cc b/components/brave_shields/browser/ad_block_regional_filters_provider.cc new file mode 100644 index 000000000000..a49b0e07ed67 --- /dev/null +++ b/components/brave_shields/browser/ad_block_regional_filters_provider.cc @@ -0,0 +1,77 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_regional_filters_provider.h" + +#include +#include +#include + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/task/thread_pool.h" +#include "brave/components/brave_shields/browser/ad_block_component_installer.h" +#include "components/component_updater/component_updater_service.h" +#include "content/public/browser/browser_task_traits.h" + +namespace brave_shields { + +AdBlockRegionalFiltersProvider::AdBlockRegionalFiltersProvider( + component_updater::ComponentUpdateService* cus, + const adblock::FilterList& catalog_entry) + : uuid_(catalog_entry.uuid), + component_id_(catalog_entry.component_id), + component_updater_service_(cus) { + // Can be nullptr in unit tests + if (cus) { + RegisterAdBlockRegionalComponent( + component_updater_service_, catalog_entry.base64_public_key, + component_id_, catalog_entry.title, + base::BindRepeating(&AdBlockRegionalFiltersProvider::OnComponentReady, + weak_factory_.GetWeakPtr())); + } +} + +AdBlockRegionalFiltersProvider::~AdBlockRegionalFiltersProvider() {} + +void AdBlockRegionalFiltersProvider::OnComponentReady( + const base::FilePath& path) { + component_path_ = path; + + base::FilePath dat_file_path = + component_path_.AppendASCII(std::string("rs-") + uuid_) + .AddExtension(FILE_PATH_LITERAL(".dat")); + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::ReadDATFileData, dat_file_path), + base::BindOnce(&AdBlockRegionalFiltersProvider::OnDATLoaded, + weak_factory_.GetWeakPtr(), true)); +} + +void AdBlockRegionalFiltersProvider::LoadDATBuffer( + base::OnceCallback + cb) { + if (component_path_.empty()) { + // If the path is not ready yet, do nothing. An update should be pushed + // soon. + return; + } + + base::FilePath dat_file_path = + component_path_.AppendASCII(std::string("rs-") + uuid_) + .AddExtension(FILE_PATH_LITERAL(".dat")); + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::ReadDATFileData, dat_file_path), + base::BindOnce(std::move(cb), true)); +} + +bool AdBlockRegionalFiltersProvider::Delete() && { + return component_updater_service_->UnregisterComponent(component_id_); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_regional_filters_provider.h b/components/brave_shields/browser/ad_block_regional_filters_provider.h new file mode 100644 index 000000000000..f6a0e63e9d34 --- /dev/null +++ b/components/brave_shields/browser/ad_block_regional_filters_provider.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_FILTERS_PROVIDER_H_ + +#include + +#include "base/callback.h" +#include "base/observer_list.h" +#include "brave/components/adblock_rust_ffi/src/wrapper.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater + +namespace base { +class FilePath; +} + +class AdBlockServiceTest; + +namespace brave_shields { + +class AdBlockRegionalFiltersProvider : public AdBlockFiltersProvider { + public: + AdBlockRegionalFiltersProvider(component_updater::ComponentUpdateService* cus, + const adblock::FilterList& catalog_entry); + ~AdBlockRegionalFiltersProvider() override; + AdBlockRegionalFiltersProvider(const AdBlockRegionalFiltersProvider&) = + delete; + AdBlockRegionalFiltersProvider& operator=( + const AdBlockRegionalFiltersProvider&) = delete; + + void LoadDATBuffer( + base::OnceCallback) override; + + bool Delete() && override; + + private: + friend class ::AdBlockServiceTest; + + void OnComponentReady(const base::FilePath&); + + base::FilePath component_path_; + std::string uuid_; + std::string component_id_; + component_updater::ComponentUpdateService* component_updater_service_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_FILTERS_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_regional_service.cc b/components/brave_shields/browser/ad_block_regional_service.cc deleted file mode 100644 index 7477fabee28b..000000000000 --- a/components/brave_shields/browser/ad_block_regional_service.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "brave/components/brave_shields/browser/ad_block_regional_service.h" - -#include -#include -#include -#include - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_restrictions.h" -#include "brave/components/adblock_rust_ffi/src/wrapper.h" -#include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" -#include "brave/components/brave_shields/browser/ad_block_service.h" -#include "brave/components/brave_shields/browser/ad_block_service_helper.h" -#include "components/prefs/pref_service.h" - -namespace brave_shields { - -std::string // NOLINT - AdBlockRegionalService::g_ad_block_regional_component_id_; // NOLINT -std::string AdBlockRegionalService:: // NOLINT - g_ad_block_regional_component_base64_public_key_; // NOLINT - -AdBlockRegionalService::AdBlockRegionalService( - const adblock::FilterList& catalog_entry, - brave_component_updater::BraveComponent::Delegate* delegate, - AdBlockRegionalService::ResourcesFileReadyCallback - resoures_file_ready_callback) - : AdBlockBaseService(delegate), - resoures_file_ready_callback_(resoures_file_ready_callback), - uuid_(catalog_entry.uuid), - title_(catalog_entry.title), - component_id_(catalog_entry.component_id), - base64_public_key_(catalog_entry.base64_public_key) {} - -AdBlockRegionalService::~AdBlockRegionalService() {} - -void AdBlockRegionalService::SetCatalogEntry(const adblock::FilterList& entry) { - DCHECK(entry.uuid == uuid_); - title_ = entry.title; - component_id_ = entry.component_id; - base64_public_key_ = entry.base64_public_key; -} - -bool AdBlockRegionalService::Init() { - AdBlockBaseService::Init(); - - Register(title_, - !g_ad_block_regional_component_id_.empty() - ? g_ad_block_regional_component_id_ - : component_id_, - !g_ad_block_regional_component_base64_public_key_.empty() - ? g_ad_block_regional_component_base64_public_key_ - : base64_public_key_); - - return true; -} - -void AdBlockRegionalService::OnComponentReady(const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) { - base::FilePath dat_file_path = - install_dir.AppendASCII(std::string("rs-") + uuid_) - .AddExtension(FILE_PATH_LITERAL(".dat")); - GetDATFileData(dat_file_path); - base::FilePath resources_file_path = - install_dir.AppendASCII(kAdBlockResourcesFilename); - - base::PostTaskAndReplyWithResult( - GetTaskRunner().get(), FROM_HERE, - base::BindOnce(&brave_component_updater::GetDATFileAsString, - resources_file_path), - base::BindOnce(&AdBlockRegionalService::OnResourcesFileDataReady, - weak_factory_.GetWeakPtr())); -} - -void AdBlockRegionalService::OnResourcesFileDataReady( - const std::string& resources) { - resoures_file_ready_callback_.Run(resources); -} - -// static -void AdBlockRegionalService::SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key) { - g_ad_block_regional_component_id_ = component_id; - g_ad_block_regional_component_base64_public_key_ = - component_base64_public_key; -} - -/////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr AdBlockRegionalServiceFactory( - const adblock::FilterList& catalog_entry, - brave_component_updater::BraveComponent::Delegate* delegate, - AdBlockRegionalService::ResourcesFileReadyCallback - resoures_file_ready_callback) { - return std::make_unique(catalog_entry, delegate, - resoures_file_ready_callback); -} - -} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_regional_service.h b/components/brave_shields/browser/ad_block_regional_service.h deleted file mode 100644 index 616fb11e586d..000000000000 --- a/components/brave_shields/browser/ad_block_regional_service.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2019 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_SERVICE_H_ -#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_SERVICE_H_ - -#include - -#include -#include -#include - -#include "base/callback.h" -#include "base/files/file_path.h" -#include "brave/components/adblock_rust_ffi/src/wrapper.h" -#include "brave/components/brave_shields/browser/ad_block_base_service.h" - -class AdBlockServiceTest; - -namespace brave_shields { - -// The brave shields service in charge of ad-block checking and init -// for a specific region. -class AdBlockRegionalService : public AdBlockBaseService { - public: - using ResourcesFileReadyCallback = - base::RepeatingCallback; - - explicit AdBlockRegionalService( - const adblock::FilterList& catalog_entry, - brave_component_updater::BraveComponent::Delegate* delegate, - ResourcesFileReadyCallback resoures_file_ready_callback); - AdBlockRegionalService(const AdBlockRegionalService&) = delete; - AdBlockRegionalService& operator=(const AdBlockRegionalService&) = delete; - ~AdBlockRegionalService() override; - - void SetCatalogEntry(const adblock::FilterList& entry); - - std::string GetUUID() const { return uuid_; } - std::string GetTitle() const { return title_; } - - protected: - bool Init() override; - void OnComponentReady(const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) override; - void OnResourcesFileDataReady(const std::string& resources); - - private: - friend class ::AdBlockServiceTest; - static std::string g_ad_block_regional_component_id_; - static std::string g_ad_block_regional_component_base64_public_key_; - static std::string g_ad_block_regional_dat_file_version_; - static void SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key); - - ResourcesFileReadyCallback resoures_file_ready_callback_; - - std::string uuid_; - std::string title_; - std::string component_id_; - std::string base64_public_key_; - - base::WeakPtrFactory weak_factory_{this}; -}; - -// Creates the AdBlockRegionalService -std::unique_ptr AdBlockRegionalServiceFactory( - const adblock::FilterList& catalog_entry, - brave_component_updater::BraveComponent::Delegate* delegate, - AdBlockRegionalService::ResourcesFileReadyCallback - resoures_file_ready_callback); - -} // namespace brave_shields - -#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_REGIONAL_SERVICE_H_ diff --git a/components/brave_shields/browser/ad_block_regional_service_manager.cc b/components/brave_shields/browser/ad_block_regional_service_manager.cc index bc70fe04c442..0c75b81b82a9 100644 --- a/components/brave_shields/browser/ad_block_regional_service_manager.cc +++ b/components/brave_shields/browser/ad_block_regional_service_manager.cc @@ -14,9 +14,10 @@ #include "base/task/post_task.h" #include "base/values.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" -#include "brave/components/brave_shields/browser/ad_block_regional_service.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_service_helper.h" +#include "brave/components/brave_shields/common/brave_shield_constants.h" #include "brave/components/brave_shields/common/features.h" #include "brave/components/brave_shields/common/pref_names.h" #include "components/prefs/pref_service.h" @@ -27,23 +28,39 @@ using adblock::FilterList; using brave_shields::features::kBraveAdblockCookieListDefault; -const char kCookieListUuid[] = "AC023D22-AE88-4060-A978-4FEEEC4221693"; - namespace brave_shields { AdBlockRegionalServiceManager::AdBlockRegionalServiceManager( - brave_component_updater::BraveComponent::Delegate* delegate) - : delegate_(delegate), - initialized_(false) { + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner) + : local_state_(local_state), + locale_(locale), + initialized_(false), + task_runner_(task_runner), + component_update_service_(cus) {} + +void AdBlockRegionalServiceManager::Init( + AdBlockResourceProvider* resource_provider, + AdBlockRegionalCatalogProvider* catalog_provider) { + DCHECK(!initialized_); + resource_provider_ = resource_provider; + catalog_provider_ = catalog_provider; + catalog_provider_->LoadRegionalCatalog( + base::BindOnce(&AdBlockRegionalServiceManager::OnRegionalCatalogLoaded, + weak_factory_.GetWeakPtr())); + catalog_provider_->AddObserver(this); + initialized_ = true; } AdBlockRegionalServiceManager::~AdBlockRegionalServiceManager() { + catalog_provider_->RemoveObserver(this); } void AdBlockRegionalServiceManager::StartRegionalServices() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + if (!local_state_) return; if (regional_catalog_.size() == 0) { @@ -53,24 +70,24 @@ void AdBlockRegionalServiceManager::StartRegionalServices() { // Enable the default regional list, but only do this once so that // user can override this setting in the future bool checked_default_region = - local_state->GetBoolean(prefs::kAdBlockCheckedDefaultRegion); + local_state_->GetBoolean(prefs::kAdBlockCheckedDefaultRegion); if (!checked_default_region) { - local_state->SetBoolean(prefs::kAdBlockCheckedDefaultRegion, true); + local_state_->SetBoolean(prefs::kAdBlockCheckedDefaultRegion, true); auto it = brave_shields::FindAdBlockFilterListByLocale(regional_catalog_, - delegate_->locale()); + locale_); if (it == regional_catalog_.end()) return; EnableFilterList(it->uuid, true); } const bool cookie_list_touched = - local_state->GetBoolean(prefs::kAdBlockCookieListSettingTouched); + local_state_->GetBoolean(prefs::kAdBlockCookieListSettingTouched); // Start all regional services associated with enabled filter lists base::AutoLock lock(regional_services_lock_); const base::DictionaryValue* regional_filters_dict = &base::Value::AsDictionaryValue( - *local_state->GetDictionary(prefs::kAdBlockRegionalFilters)); + *local_state_->GetDictionary(prefs::kAdBlockRegionalFilters)); base::Value regional_filters_dict_with_cookielist = base::Value(regional_filters_dict->Clone()); @@ -91,51 +108,51 @@ void AdBlockRegionalServiceManager::StartRegionalServices() { enabled = regional_filter_dict->FindBoolKey("enabled").value_or(false); } if (enabled) { - auto catalog_entry = brave_shields::FindAdBlockFilterListByUUID( - regional_catalog_, uuid); - if (catalog_entry != regional_catalog_.end()) { - auto regional_service = AdBlockRegionalServiceFactory( - *catalog_entry, delegate_, - base::BindRepeating(&AdBlockRegionalServiceManager::AddResources, - base::Unretained(this))); - regional_service->Start(); - regional_services_.insert( - std::make_pair(uuid, std::move(regional_service))); + auto catalog_entry = + brave_shields::FindAdBlockFilterListByUUID(regional_catalog_, uuid); + auto existing_engine = regional_services_.find(uuid); + // Iterating through locally enabled lists - don't disable any engines or + // update existing engines with a potentially new catalog entry. They'll + // be handled after a browser restart. + if (catalog_entry != regional_catalog_.end() && + existing_engine == regional_services_.end()) { + auto regional_filters_provider = + std::make_unique( + component_update_service_, *catalog_entry); + auto regional_service = + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(task_runner_)); + auto observer = + std::make_unique( + regional_service->AsWeakPtr(), regional_filters_provider.get(), + resource_provider_, task_runner_); + regional_services_.insert({uuid, std::move(regional_service)}); + regional_filters_providers_.insert( + {uuid, std::move(regional_filters_provider)}); + regional_source_observers_.insert({uuid, std::move(observer)}); } } } - - initialized_ = true; } void AdBlockRegionalServiceManager::UpdateFilterListPrefs( const std::string& uuid, bool enabled) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + if (!local_state_) return; - DictionaryPrefUpdate update(local_state, prefs::kAdBlockRegionalFilters); + DictionaryPrefUpdate update(local_state_, prefs::kAdBlockRegionalFilters); base::Value* regional_filters_dict = update.Get(); auto regional_filter_dict = base::Value(base::Value::Type::DICTIONARY); regional_filter_dict.SetBoolKey("enabled", enabled); regional_filters_dict->SetKey(uuid, std::move(regional_filter_dict)); if (uuid == kCookieListUuid) { - local_state->SetBoolean(prefs::kAdBlockCookieListSettingTouched, true); + local_state_->SetBoolean(prefs::kAdBlockCookieListSettingTouched, true); } } -bool AdBlockRegionalServiceManager::IsInitialized() const { - return initialized_; -} - bool AdBlockRegionalServiceManager::Start() { - base::AutoLock lock(regional_services_lock_); - for (const auto& regional_service : regional_services_) { - regional_service.second->Start(); - } - return true; } @@ -148,9 +165,6 @@ void AdBlockRegionalServiceManager::ShouldStartRequest( bool* did_match_exception, bool* did_match_important, std::string* mock_data_url) { - if (!IsInitialized()) - return; - base::AutoLock lock(regional_services_lock_); for (const auto& regional_service : regional_services_) { @@ -186,39 +200,50 @@ void AdBlockRegionalServiceManager::EnableTag(const std::string& tag, } } -void AdBlockRegionalServiceManager::AddResources( - const std::string& resources) { +void AdBlockRegionalServiceManager::AddResources(const std::string& resources) { base::AutoLock lock(regional_services_lock_); for (const auto& regional_service : regional_services_) { regional_service.second->AddResources(resources); } } -void AdBlockRegionalServiceManager::EnableFilterList( - const std::string& uuid, bool enabled) { +void AdBlockRegionalServiceManager::EnableFilterList(const std::string& uuid, + bool enabled) { DCHECK(!uuid.empty()); - auto catalog_entry = brave_shields::FindAdBlockFilterListByUUID( - regional_catalog_, uuid); + auto catalog_entry = + brave_shields::FindAdBlockFilterListByUUID(regional_catalog_, uuid); // Enable or disable the specified filter list - if (initialized_) { - base::AutoLock lock(regional_services_lock_); - DCHECK(catalog_entry != regional_catalog_.end()); - auto it = regional_services_.find(uuid); - if (enabled) { - DCHECK(it == regional_services_.end()); - auto regional_service = AdBlockRegionalServiceFactory( - *catalog_entry, delegate_, - base::BindRepeating(&AdBlockRegionalServiceManager::AddResources, - base::Unretained(this))); - regional_service->Start(); - regional_services_.insert( - std::make_pair(uuid, std::move(regional_service))); - } else { - DCHECK(it != regional_services_.end()); - it->second->Unregister(); - regional_services_.erase(it); - } + base::AutoLock lock(regional_services_lock_); + DCHECK(catalog_entry != regional_catalog_.end()); + auto it = regional_services_.find(uuid); + if (enabled) { + DCHECK(it == regional_services_.end()); + auto regional_filters_provider = + std::make_unique( + component_update_service_, *catalog_entry); + auto regional_service = + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(task_runner_)); + auto observer = std::make_unique( + regional_service->AsWeakPtr(), regional_filters_provider.get(), + resource_provider_, task_runner_); + regional_services_.insert({uuid, std::move(regional_service)}); + regional_filters_providers_.insert( + {uuid, std::move(regional_filters_provider)}); + regional_source_observers_.insert({uuid, std::move(observer)}); + } else { + auto observer = regional_source_observers_.find(uuid); + DCHECK(observer != regional_source_observers_.end()); + regional_source_observers_.erase(observer); + + DCHECK(it != regional_services_.end()); + regional_services_.erase(it); + + auto it2 = regional_filters_providers_.find(uuid); + DCHECK(it2 != regional_filters_providers_.end()); + std::move(*it2->second).Delete(); + regional_filters_providers_.erase(it2); } // Update preferences to reflect enabled/disabled state of specified @@ -226,7 +251,7 @@ void AdBlockRegionalServiceManager::EnableFilterList( base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&AdBlockRegionalServiceManager::UpdateFilterListPrefs, - base::Unretained(this), uuid, enabled)); + weak_factory_.GetWeakPtr(), uuid, enabled)); } absl::optional AdBlockRegionalServiceManager::UrlCosmeticResources( @@ -239,7 +264,7 @@ absl::optional AdBlockRegionalServiceManager::UrlCosmeticResources( absl::optional first_value = it->second->UrlCosmeticResources(url); - for ( ; it != regional_services_.end(); it++) { + for (; it != regional_services_.end(); it++) { absl::optional next_value = it->second->UrlCosmeticResources(url); if (first_value) { @@ -277,18 +302,9 @@ base::Value AdBlockRegionalServiceManager::HiddenClassIdSelectors( } void AdBlockRegionalServiceManager::SetRegionalCatalog( - std::vector catalog) { + std::vector catalog) { regional_catalog_ = std::move(catalog); - for (const auto& regional_service : regional_services_) { - auto catalog_entry = brave_shields::FindAdBlockFilterListByUUID( - regional_catalog_, regional_service.second->GetUUID()); - if (catalog_entry != regional_catalog_.end()) { - regional_service.second->SetCatalogEntry(*catalog_entry); - } - } - if (!initialized_) { - StartRegionalServices(); - } + StartRegionalServices(); } const std::vector& @@ -299,15 +315,14 @@ AdBlockRegionalServiceManager::GetRegionalCatalog() { std::unique_ptr AdBlockRegionalServiceManager::GetRegionalLists() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + if (!local_state_) return nullptr; const base::DictionaryValue* regional_filters_dict = &base::Value::AsDictionaryValue( - *local_state->GetDictionary(prefs::kAdBlockRegionalFilters)); + *local_state_->GetDictionary(prefs::kAdBlockRegionalFilters)); const bool cookie_list_touched = - local_state->GetBoolean(prefs::kAdBlockCookieListSettingTouched); + local_state_->GetBoolean(prefs::kAdBlockCookieListSettingTouched); auto list_value = std::make_unique(); for (const auto& region_list : regional_catalog_) { @@ -341,11 +356,21 @@ AdBlockRegionalServiceManager::GetRegionalLists() { return list_value; } +void AdBlockRegionalServiceManager::OnRegionalCatalogLoaded( + const std::string& catalog_json) { + SetRegionalCatalog(RegionalCatalogFromJSON(catalog_json)); +} + /////////////////////////////////////////////////////////////////////////////// std::unique_ptr -AdBlockRegionalServiceManagerFactory(BraveComponent::Delegate* delegate) { - return std::make_unique(delegate); +AdBlockRegionalServiceManagerFactory( + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner) { + return std::make_unique(local_state, locale, + cus, task_runner); } } // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_regional_service_manager.h b/components/brave_shields/browser/ad_block_regional_service_manager.h index 3a5db0999542..35965515c14e 100644 --- a/components/brave_shields/browser/ad_block_regional_service_manager.h +++ b/components/brave_shields/browser/ad_block_regional_service_manager.h @@ -17,6 +17,11 @@ #include "base/values.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" #include "brave/components/brave_component_updater/browser/brave_component.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" +#include "brave/components/brave_shields/browser/ad_block_regional_catalog_provider.h" +#include "brave/components/brave_shields/browser/ad_block_regional_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_resource_provider.h" +#include "brave/components/brave_shields/browser/ad_block_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" #include "url/gurl.h" @@ -35,20 +40,24 @@ class AdBlockRegionalService; // The AdBlock regional service manager, in charge of initializing and // managing regional AdBlock clients. -class AdBlockRegionalServiceManager { +class AdBlockRegionalServiceManager + : public AdBlockRegionalCatalogProvider::Observer { public: - explicit AdBlockRegionalServiceManager(BraveComponent::Delegate* delegate); + explicit AdBlockRegionalServiceManager( + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner); AdBlockRegionalServiceManager(const AdBlockRegionalServiceManager&) = delete; AdBlockRegionalServiceManager& operator=( const AdBlockRegionalServiceManager&) = delete; - ~AdBlockRegionalServiceManager(); + ~AdBlockRegionalServiceManager() override; std::unique_ptr GetRegionalLists(); void SetRegionalCatalog(std::vector catalog); const std::vector& GetRegionalCatalog(); - bool IsInitialized() const; bool Start(); void ShouldStartRequest(const GURL& url, blink::mojom::ResourceType resource_type, @@ -72,24 +81,46 @@ class AdBlockRegionalServiceManager { const std::vector& ids, const std::vector& exceptions); + void Init(AdBlockResourceProvider* resource_provider, + AdBlockRegionalCatalogProvider* catalog_provider); + + // AdBlockRegionalCatalogProvider::Observer + void OnRegionalCatalogLoaded(const std::string& catalog_json) override; + private: friend class ::AdBlockServiceTest; void StartRegionalServices(); void UpdateFilterListPrefs(const std::string& uuid, bool enabled); - raw_ptr delegate_ = - nullptr; // NOT OWNED + raw_ptr local_state_; + std::string locale_; bool initialized_; base::Lock regional_services_lock_; - std::map> + std::map> regional_services_; + std::map> + regional_filters_providers_; + std::map> + regional_source_observers_; std::vector regional_catalog_; + + scoped_refptr task_runner_; + raw_ptr component_update_service_; + raw_ptr resource_provider_; + raw_ptr catalog_provider_; + + base::WeakPtrFactory weak_factory_{this}; }; // Creates the AdBlockRegionalServiceManager std::unique_ptr -AdBlockRegionalServiceManagerFactory(BraveComponent::Delegate* delegate); +AdBlockRegionalServiceManagerFactory( + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner); } // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_resource_provider.cc b/components/brave_shields/browser/ad_block_resource_provider.cc new file mode 100644 index 000000000000..7c1b94a56fc5 --- /dev/null +++ b/components/brave_shields/browser/ad_block_resource_provider.cc @@ -0,0 +1,35 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_resource_provider.h" + +#include + +namespace brave_shields { + +AdBlockResourceProvider::AdBlockResourceProvider() {} + +AdBlockResourceProvider::~AdBlockResourceProvider() {} + +void AdBlockResourceProvider::AddObserver( + AdBlockResourceProvider::Observer* observer) { + if (!observers_.HasObserver(observer)) + observers_.AddObserver(observer); +} + +void AdBlockResourceProvider::RemoveObserver( + AdBlockResourceProvider::Observer* observer) { + if (observers_.HasObserver(observer)) + observers_.RemoveObserver(observer); +} + +void AdBlockResourceProvider::OnResourcesLoaded( + const std::string& resources_json) { + for (auto& observer : observers_) { + observer.OnResourcesLoaded(resources_json); + } +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_resource_provider.h b/components/brave_shields/browser/ad_block_resource_provider.h new file mode 100644 index 000000000000..be726faed78f --- /dev/null +++ b/components/brave_shields/browser/ad_block_resource_provider.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_RESOURCE_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_RESOURCE_PROVIDER_H_ + +#include + +#include "base/callback.h" +#include "base/observer_list.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using brave_component_updater::DATFileDataBuffer; + +namespace brave_shields { + +// Interface for any source that can load resource replacements into an adblock +// engine. +class AdBlockResourceProvider { + public: + class Observer : public base::CheckedObserver { + public: + virtual void OnResourcesLoaded(const std::string& resources_json) = 0; + }; + + AdBlockResourceProvider(); + virtual ~AdBlockResourceProvider(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + virtual void LoadResources( + base::OnceCallback) = 0; + + protected: + void OnResourcesLoaded(const std::string& resources_json); + + private: + base::ObserverList observers_; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_RESOURCE_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_service.cc b/components/brave_shields/browser/ad_block_service.cc index 03cebf45b42d..98f02784d9d2 100644 --- a/components/brave_shields/browser/ad_block_service.cc +++ b/components/brave_shields/browser/ad_block_service.cc @@ -18,7 +18,9 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_default_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" #include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h" #include "brave/components/brave_shields/browser/ad_block_service_helper.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h" @@ -33,7 +35,6 @@ #include "url/origin.h" #define DAT_FILE "rs-ABPFilterParserData.dat" -#define REGIONAL_CATALOG "regional_catalog.json" namespace brave_shields { @@ -59,9 +60,48 @@ void AdBlockServiceDomainResolver(const char* host, } // namespace -std::string AdBlockService::g_ad_block_component_id_(kAdBlockComponentId); -std::string AdBlockService::g_ad_block_component_base64_public_key_( - kAdBlockComponentBase64PublicKey); +AdBlockService::SourceProviderObserver::SourceProviderObserver( + base::WeakPtr adblock_engine, + AdBlockFiltersProvider* filters_provider, + AdBlockResourceProvider* resource_provider, + scoped_refptr task_runner) + : adblock_engine_(adblock_engine), + filters_provider_(filters_provider), + resource_provider_(resource_provider), + task_runner_(task_runner) { + filters_provider_->AddObserver(this); + filters_provider_->LoadDAT(this); +} + +AdBlockService::SourceProviderObserver::~SourceProviderObserver() { + filters_provider_->RemoveObserver(this); + resource_provider_->RemoveObserver(this); +} + +void AdBlockService::SourceProviderObserver::OnDATLoaded( + bool deserialize, + const DATFileDataBuffer& dat_buf) { + deserialize_ = deserialize; + dat_buf_ = std::move(dat_buf); + // multiple AddObserver calls are ignored + resource_provider_->AddObserver(this); + resource_provider_->LoadResources(base::BindOnce( + &SourceProviderObserver::OnResourcesLoaded, weak_factory_.GetWeakPtr())); +} + +void AdBlockService::SourceProviderObserver::OnResourcesLoaded( + const std::string& resources_json) { + if (dat_buf_.empty()) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&AdBlockEngine::AddResources, adblock_engine_, + resources_json)); + } else { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&AdBlockEngine::Load, adblock_engine_, deserialize_, + std::move(dat_buf_), resources_json)); + } +} void AdBlockService::ShouldStartRequest( const GURL& url, @@ -72,16 +112,14 @@ void AdBlockService::ShouldStartRequest( bool* did_match_exception, bool* did_match_important, std::string* mock_data_url) { - if (!IsInitialized()) - return; - + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (aggressive_blocking || base::FeatureList::IsEnabled( brave_shields::features::kBraveAdblockDefault1pBlocking) || !SameDomainOrHost( url, url::Origin::CreateFromNormalizedTuple("https", tab_host, 80), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) { - AdBlockBaseService::ShouldStartRequest( + default_service()->ShouldStartRequest( url, resource_type, tab_host, aggressive_blocking, did_match_rule, did_match_exception, did_match_important, mock_data_url); if (did_match_important && *did_match_important) { @@ -112,8 +150,9 @@ absl::optional AdBlockService::GetCspDirectives( const GURL& url, blink::mojom::ResourceType resource_type, const std::string& tab_host) { + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); auto csp_directives = - AdBlockBaseService::GetCspDirectives(url, resource_type, tab_host); + default_service()->GetCspDirectives(url, resource_type, tab_host); const auto regional_csp = regional_service_manager()->GetCspDirectives( url, resource_type, tab_host); @@ -128,8 +167,9 @@ absl::optional AdBlockService::GetCspDirectives( absl::optional AdBlockService::UrlCosmeticResources( const std::string& url) { + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); absl::optional resources = - AdBlockBaseService::UrlCosmeticResources(url); + default_service()->UrlCosmeticResources(url); if (!resources || !resources->is_dict()) { return resources; @@ -175,8 +215,9 @@ base::Value AdBlockService::HiddenClassIdSelectors( const std::vector& classes, const std::vector& ids, const std::vector& exceptions) { + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); base::Value hide_selectors = - AdBlockBaseService::HiddenClassIdSelectors(classes, ids, exceptions); + default_service()->HiddenClassIdSelectors(classes, ids, exceptions); base::Value regional_selectors = regional_service_manager()->HiddenClassIdSelectors(classes, ids, @@ -212,95 +253,101 @@ base::Value AdBlockService::HiddenClassIdSelectors( } AdBlockRegionalServiceManager* AdBlockService::regional_service_manager() { - if (!regional_service_manager_) + if (!regional_service_manager_) { regional_service_manager_ = brave_shields::AdBlockRegionalServiceManagerFactory( - component_delegate_); + local_state_, locale_, component_update_service_, GetTaskRunner()); + regional_service_manager_->Init(default_filters_provider_.get(), + default_filters_provider_.get()); + } return regional_service_manager_.get(); } -brave_shields::AdBlockCustomFiltersService* -AdBlockService::custom_filters_service() { - if (!custom_filters_service_) +AdBlockEngine* AdBlockService::default_service() { + if (!default_service_) { + default_service_ = + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(GetTaskRunner())); + default_service_observer_ = std::make_unique( + default_service_->AsWeakPtr(), default_filters_provider_.get(), + default_filters_provider_.get(), GetTaskRunner()); + } + return default_service_.get(); +} + +AdBlockEngine* AdBlockService::custom_filters_service() { + if (!custom_filters_service_) { custom_filters_service_ = - brave_shields::AdBlockCustomFiltersServiceFactory(component_delegate_); + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(GetTaskRunner())); + custom_filters_service_observer_ = std::make_unique( + custom_filters_service_->AsWeakPtr(), custom_filters_provider_.get(), + default_filters_provider_.get(), GetTaskRunner()); + } return custom_filters_service_.get(); } +brave_shields::AdBlockCustomFiltersProvider* +AdBlockService::custom_filters_provider() { + return custom_filters_provider_.get(); +} + brave_shields::AdBlockSubscriptionServiceManager* AdBlockService::subscription_service_manager() { + if (!subscription_service_manager_->IsInitialized()) { + subscription_service_manager_->Init(default_filters_provider_.get()); + } return subscription_service_manager_.get(); } AdBlockService::AdBlockService( - brave_component_updater::BraveComponent::Delegate* delegate, + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner, std::unique_ptr subscription_service_manager) - : AdBlockBaseService(delegate), - component_delegate_(delegate), - subscription_service_manager_(std::move(subscription_service_manager)) {} + : local_state_(local_state), + locale_(locale), + component_update_service_(cus), + task_runner_(task_runner), + custom_filters_service_(nullptr, base::OnTaskRunnerDeleter(task_runner_)), + default_service_(nullptr, base::OnTaskRunnerDeleter(task_runner_)), + subscription_service_manager_(std::move(subscription_service_manager)) { + default_filters_provider_ = + std::make_unique( + component_update_service_); + custom_filters_provider_ = + std::make_unique( + local_state_); +} AdBlockService::~AdBlockService() {} -bool AdBlockService::Init() { +bool AdBlockService::Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Initializes adblock-rust's domain resolution implementation adblock::SetDomainResolver(AdBlockServiceDomainResolver); - if (!AdBlockBaseService::Init()) - return false; + // Initialize each service: + default_service(); + custom_filters_service(); + regional_service_manager(); + subscription_service_manager(); - Register(kAdBlockComponentName, g_ad_block_component_id_, - g_ad_block_component_base64_public_key_); return true; } -void AdBlockService::OnComponentReady(const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) { - // Regional service manager depends on regional catalog loading - custom_filters_service()->Start(); - subscription_service_manager()->Start(); - - base::FilePath dat_file_path = install_dir.AppendASCII(DAT_FILE); - GetDATFileData(dat_file_path); - - base::FilePath regional_catalog_file_path = - install_dir.AppendASCII(REGIONAL_CATALOG); - - base::FilePath resources_file_path = - install_dir.AppendASCII(kAdBlockResourcesFilename); - base::PostTaskAndReplyWithResult( - GetTaskRunner().get(), FROM_HERE, - base::BindOnce(&brave_component_updater::GetDATFileAsString, - resources_file_path), - base::BindOnce(&AdBlockService::OnResourcesFileDataReady, - weak_factory_.GetWeakPtr())); - base::PostTaskAndReplyWithResult( - GetTaskRunner().get(), FROM_HERE, - base::BindOnce(&brave_component_updater::GetDATFileAsString, - regional_catalog_file_path), - base::BindOnce(&AdBlockService::OnRegionalCatalogFileDataReady, - weak_factory_.GetWeakPtr())); -} - -void AdBlockService::OnResourcesFileDataReady(const std::string& resources) { - AddResources(resources); - custom_filters_service()->AddResources(resources); -} - -void AdBlockService::OnRegionalCatalogFileDataReady( - const std::string& catalog_json) { - regional_service_manager()->SetRegionalCatalog( - RegionalCatalogFromJSON(catalog_json)); - regional_service_manager()->Start(); +void AdBlockService::EnableTag(const std::string& tag, bool enabled) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Tags only need to be modified for the default engine. + GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AdBlockEngine::EnableTag, + default_service()->AsWeakPtr(), tag, enabled)); } -// static -void AdBlockService::SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key) { - g_ad_block_component_id_ = component_id; - g_ad_block_component_base64_public_key_ = component_base64_public_key; +base::SequencedTaskRunner* AdBlockService::GetTaskRunner() { + return task_runner_.get(); } void RegisterPrefsForAdBlockService(PrefRegistrySimple* registry) { @@ -311,4 +358,28 @@ void RegisterPrefsForAdBlockService(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(prefs::kAdBlockCheckedDefaultRegion, false); } +AdBlockResourceProvider* AdBlockService::resource_provider() { + return default_filters_provider_.get(); +} + +void AdBlockService::UseSourceProvidersForTest( + AdBlockFiltersProvider* source_provider, + AdBlockResourceProvider* resource_provider) { + default_service_observer_ = std::make_unique( + default_service_->AsWeakPtr(), source_provider, resource_provider, + GetTaskRunner()); +} + +void AdBlockService::UseCustomSourceProvidersForTest( + AdBlockFiltersProvider* source_provider, + AdBlockResourceProvider* resource_provider) { + custom_filters_service_observer_ = std::make_unique( + custom_filters_service_->AsWeakPtr(), source_provider, resource_provider, + GetTaskRunner()); +} + +bool AdBlockService::TagExistsForTest(const std::string& tag) { + return default_service()->TagExists(tag); +} + } // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_service.h b/components/brave_shields/browser/ad_block_service.h index c2f3c206c3f9..cd9d29180dce 100644 --- a/components/brave_shields/browser/ad_block_service.h +++ b/components/brave_shields/browser/ad_block_service.h @@ -13,47 +13,82 @@ #include #include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/task/sequenced_task_runner.h" #include "base/values.h" -#include "brave/components/brave_shields/browser/ad_block_base_service.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_resource_provider.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_registry_simple.h" #include "content/public/browser/browser_thread.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" +#include "url/gurl.h" class AdBlockServiceTest; +class BraveAdBlockTPNetworkDelegateHelperTest; class DomainBlockTest; +class EphemeralStorage1pDomainBlockBrowserTest; +class PerfPredictorTabHelperTest; class PrefChangeRegistrar; class PrefService; -using brave_component_updater::BraveComponent; +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater namespace brave_shields { +class AdBlockEngine; +class AdBlockDefaultFiltersProvider; class AdBlockRegionalServiceManager; -class AdBlockCustomFiltersService; +class AdBlockCustomFiltersProvider; +class AdBlockRegionalCatalogProvider; class AdBlockSubscriptionServiceManager; -const char kAdBlockResourcesFilename[] = "resources.json"; -const char kAdBlockComponentName[] = "Brave Ad Block Updater"; -const char kAdBlockComponentId[] = "cffkpbalmllkdoenhmdmpbkajipdjfam"; -const char kAdBlockComponentBase64PublicKey[] = - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0qzJmHSgIiw7IGFCxij" - "1NnB5hJ5ZQ1LKW9htL4EBOaMJvmqaDs/wfq0nw/goBHWsqqkMBynRTu2Hxxirvdb" - "cugn1Goys5QKPgAvKwDHJp9jlnADWm5xQvPQ4GE1mK1/I3ka9cEOCzPW6GI+wGLi" - "VPx9VZrxHHsSBIJRaEB5Tyi5bj0CZ+kcfMnRTsXIBw3C6xJgCVKISQUkd8mawVvG" - "vqOhBOogCdb9qza5eJ1Cgx8RWKucFfaWWxKLOelCiBMT1Hm1znAoVBHG/blhJJOD" - "5HcH/heRrB4MvrE1J76WF3fvZ03aHVcnlLtQeiNNOZ7VbBDXdie8Nomf/QswbBGa" - "VwIDAQAB"; - // The brave shields service in charge of ad-block checking and init. -class AdBlockService : public AdBlockBaseService { +class AdBlockService { public: + class SourceProviderObserver : public AdBlockResourceProvider::Observer, + public AdBlockFiltersProvider::Observer { + public: + SourceProviderObserver( + base::WeakPtr adblock_engine, + AdBlockFiltersProvider* source_provider, + AdBlockResourceProvider* resource_provider, + scoped_refptr task_runner); + SourceProviderObserver(const SourceProviderObserver&) = delete; + SourceProviderObserver& operator=(const SourceProviderObserver&) = delete; + ~SourceProviderObserver() override; + + private: + // AdBlockFiltersProvider::Observer + void OnDATLoaded(bool deserialize, + const DATFileDataBuffer& dat_buf) override; + + // AdBlockResourceProvider::Observer + void OnResourcesLoaded(const std::string& resources_json) override; + + bool deserialize_; + DATFileDataBuffer dat_buf_; + base::WeakPtr adblock_engine_; + raw_ptr filters_provider_; // not owned + raw_ptr resource_provider_; // not owned + scoped_refptr task_runner_; + + base::WeakPtrFactory weak_factory_{this}; + }; + explicit AdBlockService( - BraveComponent::Delegate* delegate, + PrefService* local_state, + std::string locale, + component_updater::ComponentUpdateService* cus, + scoped_refptr task_runner, std::unique_ptr manager); AdBlockService(const AdBlockService&) = delete; AdBlockService& operator=(const AdBlockService&) = delete; - ~AdBlockService() override; + ~AdBlockService(); void ShouldStartRequest(const GURL& url, blink::mojom::ResourceType resource_type, @@ -62,49 +97,74 @@ class AdBlockService : public AdBlockBaseService { bool* did_match_rule, bool* did_match_exception, bool* did_match_important, - std::string* mock_data_url) override; + std::string* mock_data_url); absl::optional GetCspDirectives( const GURL& url, blink::mojom::ResourceType resource_type, const std::string& tab_host); - absl::optional UrlCosmeticResources( - const std::string& url) override; + absl::optional UrlCosmeticResources(const std::string& url); base::Value HiddenClassIdSelectors( const std::vector& classes, const std::vector& ids, - const std::vector& exceptions) override; + const std::vector& exceptions); AdBlockRegionalServiceManager* regional_service_manager(); - AdBlockCustomFiltersService* custom_filters_service(); + AdBlockEngine* custom_filters_service(); + AdBlockEngine* default_service(); AdBlockSubscriptionServiceManager* subscription_service_manager(); - protected: - bool Init() override; - void OnComponentReady(const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) override; - void OnResourcesFileDataReady(const std::string& resources); - void OnRegionalCatalogFileDataReady(const std::string& catalog_json); + AdBlockCustomFiltersProvider* custom_filters_provider(); + + void EnableTag(const std::string& tag, bool enabled); + + base::SequencedTaskRunner* GetTaskRunner(); + + bool Start(); private: + friend class ::BraveAdBlockTPNetworkDelegateHelperTest; friend class ::AdBlockServiceTest; friend class ::DomainBlockTest; - static std::string g_ad_block_component_id_; - static std::string g_ad_block_component_base64_public_key_; + friend class ::EphemeralStorage1pDomainBlockBrowserTest; + friend class ::PerfPredictorTabHelperTest; + static std::string g_ad_block_dat_file_version_; - static void SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key); - raw_ptr component_delegate_ = nullptr; + AdBlockResourceProvider* resource_provider(); + + void UseSourceProvidersForTest(AdBlockFiltersProvider* source_provider, + AdBlockResourceProvider* resource_provider); + void UseCustomSourceProvidersForTest( + AdBlockFiltersProvider* source_provider, + AdBlockResourceProvider* resource_provider); + bool TagExistsForTest(const std::string& tag); + + raw_ptr local_state_; + std::string locale_; + + raw_ptr component_update_service_; + + scoped_refptr task_runner_; std::unique_ptr regional_service_manager_; - std::unique_ptr + std::unique_ptr custom_filters_service_; + std::unique_ptr + default_service_; std::unique_ptr subscription_service_manager_; + std::unique_ptr + custom_filters_provider_; + std::unique_ptr + default_filters_provider_; + + std::unique_ptr default_service_observer_; + std::unique_ptr custom_filters_service_observer_; + + SEQUENCE_CHECKER(sequence_checker_); + base::WeakPtrFactory weak_factory_{this}; }; diff --git a/components/brave_shields/browser/ad_block_subscription_filters_provider.cc b/components/brave_shields/browser/ad_block_subscription_filters_provider.cc new file mode 100644 index 000000000000..537feb9b1602 --- /dev/null +++ b/components/brave_shields/browser/ad_block_subscription_filters_provider.cc @@ -0,0 +1,35 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/ad_block_subscription_filters_provider.h" + +#include + +#include "base/logging.h" +#include "base/task/thread_pool.h" +#include "brave/components/brave_shields/common/pref_names.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" + +namespace brave_shields { + +AdBlockSubscriptionFiltersProvider::AdBlockSubscriptionFiltersProvider( + PrefService* local_state, + base::FilePath list_file) + : list_file_(list_file) {} + +AdBlockSubscriptionFiltersProvider::~AdBlockSubscriptionFiltersProvider() {} + +void AdBlockSubscriptionFiltersProvider::LoadDATBuffer( + base::OnceCallback + cb) { + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&brave_component_updater::ReadDATFileData, list_file_), + base::BindOnce(std::move(cb), false)); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_subscription_filters_provider.h b/components/brave_shields/browser/ad_block_subscription_filters_provider.h new file mode 100644 index 000000000000..7b6a34e30553 --- /dev/null +++ b/components/brave_shields/browser/ad_block_subscription_filters_provider.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_FILTERS_PROVIDER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" + +using brave_component_updater::DATFileDataBuffer; + +class PrefService; + +namespace brave_shields { + +class AdBlockSubscriptionFiltersProvider : public AdBlockFiltersProvider { + public: + AdBlockSubscriptionFiltersProvider(PrefService* local_state, + base::FilePath list_file); + AdBlockSubscriptionFiltersProvider( + const AdBlockSubscriptionFiltersProvider&) = delete; + AdBlockSubscriptionFiltersProvider& operator=( + const AdBlockSubscriptionFiltersProvider&) = delete; + ~AdBlockSubscriptionFiltersProvider() override; + + void LoadDATBuffer( + base::OnceCallback) override; + + private: + base::FilePath list_file_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_FILTERS_PROVIDER_H_ diff --git a/components/brave_shields/browser/ad_block_subscription_service.cc b/components/brave_shields/browser/ad_block_subscription_service.cc deleted file mode 100644 index f5fba60718b5..000000000000 --- a/components/brave_shields/browser/ad_block_subscription_service.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2021 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "brave/components/brave_shields/browser/ad_block_subscription_service.h" - -#include "base/files/file_path.h" -#include "base/json/json_value_converter.h" -#include "base/json/values_util.h" -#include "base/logging.h" -#include "base/strings/string_piece.h" -#include "brave/components/brave_shields/browser/ad_block_service.h" -#include "brave/components/brave_shields/browser/ad_block_service_helper.h" -#include "brave/components/brave_shields/common/brave_shield_constants.h" - -namespace brave_shields { - -namespace { -bool SkipGURLField(base::StringPiece value, GURL* field) { - return true; -} - -bool ParseTimeValue(const base::Value* value, base::Time* field) { - auto time = base::ValueToTime(value); - if (!time) { - return false; - } - *field = *time; - return true; -} -} // namespace - -void SubscriptionInfo::RegisterJSONConverter( - base::JSONValueConverter* converter) { - // The `subscription_url` field is skipped, as it's not stored within the - // JSON value and should be populated externally. - converter->RegisterCustomField( - "subscription_url", &SubscriptionInfo::subscription_url, &SkipGURLField); - converter->RegisterCustomValueField( - "last_update_attempt", &SubscriptionInfo::last_update_attempt, - &ParseTimeValue); - converter->RegisterCustomValueField( - "last_successful_update_attempt", - &SubscriptionInfo::last_successful_update_attempt, &ParseTimeValue); - converter->RegisterBoolField("enabled", &SubscriptionInfo::enabled); -} - -AdBlockSubscriptionService::AdBlockSubscriptionService( - const SubscriptionInfo& info, - const base::FilePath list_file, - brave_component_updater::BraveComponent::Delegate* delegate) - : AdBlockBaseService(delegate), - subscription_url_(info.subscription_url), - list_file_(list_file), - load_on_start_(info.last_successful_update_attempt != base::Time::Min()), - initialized_(false) {} - -AdBlockSubscriptionService::~AdBlockSubscriptionService() {} - -bool AdBlockSubscriptionService::Init() { - if (!AdBlockBaseService::Init()) - return false; - - // if we already have local data, go ahead and load it - if (load_on_start_) { - load_on_start_ = false; - ReloadList(); - // return false so we don't set the component to initialized until the data - // is loaded - return false; - } - - return initialized_; -} - -void AdBlockSubscriptionService::ReloadList() { - GetDATFileData(list_file_, false, - base::BindOnce(&AdBlockSubscriptionService::OnListLoaded, - weak_factory_.GetWeakPtr())); -} - -void AdBlockSubscriptionService::OnListLoaded() { - Start(); - initialized_ = true; -} - -} // namespace brave_shields diff --git a/components/brave_shields/browser/ad_block_subscription_service.h b/components/brave_shields/browser/ad_block_subscription_service.h deleted file mode 100644 index 16072c697398..000000000000 --- a/components/brave_shields/browser/ad_block_subscription_service.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2021 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_SERVICE_H_ -#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_SERVICE_H_ - -#include -#include -#include - -#include "base/files/file_path.h" -#include "base/time/time.h" -#include "brave/components/brave_shields/browser/ad_block_base_service.h" -#include "url/gurl.h" - -namespace base { -template -class JSONValueConverter; -} - -class AdBlockServiceTest; - -namespace brave_shields { - -struct SubscriptionInfo { - // The URL used to fetch the list, which is also used as a unique identifier - // for a subscription service. - GURL subscription_url; - - // These are base::Time::Min() if no download has been - // attempted/succeeded. If a subscription has been successfully downloaded, - // both of these are exactly equal. - base::Time last_update_attempt; - base::Time last_successful_update_attempt; - - // Any enabled list will be queried during network requests and page loads, - // otherwise it will be bypassed. Disabled lists will not be automatically - // updated. - bool enabled; - - static void RegisterJSONConverter( - base::JSONValueConverter*); -}; - -// The brave shields service in charge of ad-block checking and init -// for a custom filter list subscription. -class AdBlockSubscriptionService : public AdBlockBaseService { - public: - using OnLoadCallback = base::RepeatingCallback; - explicit AdBlockSubscriptionService( - const SubscriptionInfo& info, - base::FilePath list_file, - brave_component_updater::BraveComponent::Delegate* delegate); - ~AdBlockSubscriptionService() override; - - void ReloadList(); - - bool Init() override; - - private: - friend class ::AdBlockServiceTest; - - void OnListLoaded(); - - GURL subscription_url_; - base::FilePath list_file_; - bool load_on_start_; - bool initialized_; - - base::WeakPtrFactory weak_factory_{this}; - - AdBlockSubscriptionService(const AdBlockSubscriptionService&) = delete; - AdBlockSubscriptionService& operator=(const AdBlockSubscriptionService&) = - delete; -}; - -} // namespace brave_shields - -#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_AD_BLOCK_SUBSCRIPTION_SERVICE_H_ diff --git a/components/brave_shields/browser/ad_block_subscription_service_manager.cc b/components/brave_shields/browser/ad_block_subscription_service_manager.cc index f101586d9f13..9d36732c99e6 100644 --- a/components/brave_shields/browser/ad_block_subscription_service_manager.cc +++ b/components/brave_shields/browser/ad_block_subscription_service_manager.cc @@ -11,6 +11,7 @@ #include "base/base64url.h" #include "base/bind.h" +#include "base/containers/contains.h" #include "base/files/file_util.h" #include "base/json/json_value_converter.h" #include "base/json/values_util.h" @@ -20,8 +21,9 @@ #include "base/time/time.h" #include "base/values.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" #include "brave/components/brave_shields/browser/ad_block_service_helper.h" -#include "brave/components/brave_shields/browser/ad_block_subscription_service.h" +#include "brave/components/brave_shields/browser/ad_block_subscription_filters_provider.h" #include "brave/components/brave_shields/browser/ad_block_subscription_service_manager_observer.h" #include "brave/components/brave_shields/common/brave_shield_constants.h" #include "brave/components/brave_shields/common/pref_names.h" @@ -37,6 +39,19 @@ base::TimeDelta* g_testing_subscription_retry_interval; namespace { +bool SkipGURLField(base::StringPiece value, GURL* field) { + return true; +} + +bool ParseTimeValue(const base::Value* value, base::Time* field) { + auto time = base::ValueToTime(value); + if (!time) { + return false; + } + *field = *time; + return true; +} + const base::TimeDelta kListUpdateInterval = base::Days(7); const base::TimeDelta kListRetryInterval = base::Hours(1); const base::TimeDelta kListCheckInitialDelay = base::Minutes(1); @@ -60,12 +75,30 @@ const base::FilePath::CharType kSubscriptionsDir[] = } // namespace +void SubscriptionInfo::RegisterJSONConverter( + base::JSONValueConverter* converter) { + // The `subscription_url` field is skipped, as it's not stored within the + // JSON value and should be populated externally. + converter->RegisterCustomField( + "subscription_url", &SubscriptionInfo::subscription_url, &SkipGURLField); + converter->RegisterCustomValueField( + "last_update_attempt", &SubscriptionInfo::last_update_attempt, + &ParseTimeValue); + converter->RegisterCustomValueField( + "last_successful_update_attempt", + &SubscriptionInfo::last_successful_update_attempt, &ParseTimeValue); + converter->RegisterBoolField("enabled", &SubscriptionInfo::enabled); +} + AdBlockSubscriptionServiceManager::AdBlockSubscriptionServiceManager( - brave_component_updater::BraveComponent::Delegate* delegate, + PrefService* local_state, + scoped_refptr task_runner, AdBlockSubscriptionDownloadManager::DownloadManagerGetter download_manager_getter, const base::FilePath& profile_dir) - : delegate_(delegate), + : initialized_(false), + local_state_(local_state), + task_runner_(task_runner), subscription_path_(profile_dir.Append(kSubscriptionsDir)), subscriptions_(new base::DictionaryValue()), subscription_update_timer_( @@ -76,6 +109,16 @@ AdBlockSubscriptionServiceManager::AdBlockSubscriptionServiceManager( weak_ptr_factory_.GetWeakPtr())); } +void AdBlockSubscriptionServiceManager::Init( + AdBlockResourceProvider* resource_provider) { + resource_provider_ = resource_provider; + initialized_ = true; +} + +bool AdBlockSubscriptionServiceManager::IsInitialized() { + return initialized_; +} + AdBlockSubscriptionServiceManager::~AdBlockSubscriptionServiceManager() {} base::FilePath AdBlockSubscriptionServiceManager::GetSubscriptionPath( @@ -108,15 +151,14 @@ GURL AdBlockSubscriptionServiceManager::GetListTextFileUrl( void AdBlockSubscriptionServiceManager::OnUpdateTimer( component_updater::TimerUpdateScheduler::OnFinishedCallback on_finished) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + if (!local_state_) return; base::AutoLock lock(subscription_services_lock_); subscriptions_ = base::DictionaryValue::From(base::Value::ToUniquePtrValue( - local_state->GetDictionary(prefs::kAdBlockListSubscriptions)->Clone())); + local_state_->GetDictionary(prefs::kAdBlockListSubscriptions)->Clone())); for (base::DictionaryValue::Iterator it(*subscriptions_); !it.IsAtEnd(); it.Advance()) { @@ -157,23 +199,40 @@ void AdBlockSubscriptionServiceManager::StartDownload(const GURL& sub_url, void AdBlockSubscriptionServiceManager::CreateSubscription( const GURL& sub_url) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (base::Contains(subscription_services_, sub_url)) { + return; + } + SubscriptionInfo info; info.subscription_url = sub_url; info.last_update_attempt = base::Time(); info.last_successful_update_attempt = base::Time(); info.enabled = true; - auto subscription_service = std::make_unique( - info, GetSubscriptionPath(sub_url).Append(kCustomSubscriptionListText), - delegate_); + auto subscription_service = + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(task_runner_)); UpdateSubscriptionPrefs(sub_url, info); + auto subscription_filters_provider = + std::make_unique( + local_state_, + GetSubscriptionPath(sub_url).Append(kCustomSubscriptionListText)); + auto observer = std::make_unique( + subscription_service->AsWeakPtr(), subscription_filters_provider.get(), + resource_provider_, task_runner_); + { base::AutoLock lock(subscription_services_lock_); // this could allow more than one service for a given url subscription_services_.insert( std::make_pair(sub_url, std::move(subscription_service))); + subscription_filters_providers_.insert( + std::make_pair(sub_url, std::move(subscription_filters_provider))); + subscription_source_observers_.insert( + std::make_pair(sub_url, std::move(observer))); } StartDownload(sub_url, true); @@ -181,7 +240,7 @@ void AdBlockSubscriptionServiceManager::CreateSubscription( std::vector AdBlockSubscriptionServiceManager::GetSubscriptions() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto infos = std::vector(); for (const auto& subscription_service : subscription_services_) { @@ -195,7 +254,7 @@ AdBlockSubscriptionServiceManager::GetSubscriptions() { void AdBlockSubscriptionServiceManager::EnableSubscription(const GURL& sub_url, bool enabled) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto info = GetInfo(sub_url); DCHECK(info); @@ -206,12 +265,18 @@ void AdBlockSubscriptionServiceManager::EnableSubscription(const GURL& sub_url, void AdBlockSubscriptionServiceManager::DeleteSubscription( const GURL& sub_url) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); { base::AutoLock lock(subscription_services_lock_); + auto observer = subscription_source_observers_.find(sub_url); + DCHECK(observer != subscription_source_observers_.end()); + subscription_source_observers_.erase(observer); auto it = subscription_services_.find(sub_url); DCHECK(it != subscription_services_.end()); subscription_services_.erase(it); + auto it2 = subscription_filters_providers_.find(sub_url); + DCHECK(it2 != subscription_filters_providers_.end()); + subscription_filters_providers_.erase(it2); } ClearSubscriptionPrefs(sub_url); @@ -225,13 +290,13 @@ void AdBlockSubscriptionServiceManager::DeleteSubscription( void AdBlockSubscriptionServiceManager::RefreshSubscription(const GURL& sub_url, bool from_ui) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); StartDownload(sub_url, true); } void AdBlockSubscriptionServiceManager::OnGetDownloadManager( AdBlockSubscriptionDownloadManager* download_manager) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); download_manager_ = download_manager->AsWeakPtr(); // base::Unretained is ok here because AdBlockSubscriptionServiceManager will // outlive AdBlockSubscriptionDownloadManager @@ -277,15 +342,14 @@ absl::optional AdBlockSubscriptionServiceManager::GetInfo( } void AdBlockSubscriptionServiceManager::LoadSubscriptionServices() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + if (!local_state_) return; base::AutoLock lock(subscription_services_lock_); subscriptions_ = base::DictionaryValue::From(base::Value::ToUniquePtrValue( - local_state->GetDictionary(prefs::kAdBlockListSubscriptions)->Clone())); + local_state_->GetDictionary(prefs::kAdBlockListSubscriptions)->Clone())); for (base::DictionaryValue::Iterator it(*subscriptions_); !it.IsAtEnd(); it.Advance()) { @@ -297,13 +361,25 @@ void AdBlockSubscriptionServiceManager::LoadSubscriptionServices() { GURL sub_url(key); info = BuildInfoFromDict(sub_url, list_subscription_dict); - auto subscription_service = std::make_unique( - info, - GetSubscriptionPath(sub_url).Append(kCustomSubscriptionListText), - delegate_); + auto subscription_service = + std::unique_ptr( + new AdBlockEngine(), base::OnTaskRunnerDeleter(task_runner_)); + + auto subscription_filters_provider = + std::make_unique( + local_state_, + GetSubscriptionPath(sub_url).Append(kCustomSubscriptionListText)); + auto observer = std::make_unique( + subscription_service->AsWeakPtr(), + subscription_filters_provider.get(), resource_provider_, + task_runner_); subscription_services_.insert( std::make_pair(sub_url, std::move(subscription_service))); + subscription_filters_providers_.insert( + std::make_pair(sub_url, std::move(subscription_filters_provider))); + subscription_source_observers_.insert( + std::make_pair(sub_url, std::move(observer))); } } } @@ -313,12 +389,11 @@ void AdBlockSubscriptionServiceManager::LoadSubscriptionServices() { void AdBlockSubscriptionServiceManager::UpdateSubscriptionPrefs( const GURL& sub_url, const SubscriptionInfo& info) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!local_state_) return; - DictionaryPrefUpdate update(local_state, prefs::kAdBlockListSubscriptions); + DictionaryPrefUpdate update(local_state_, prefs::kAdBlockListSubscriptions); base::Value* subscriptions_dict = update.Get(); auto subscription_dict = base::Value(base::Value::Type::DICTIONARY); subscription_dict.SetBoolKey("enabled", info.enabled); @@ -339,12 +414,11 @@ void AdBlockSubscriptionServiceManager::UpdateSubscriptionPrefs( // subscription. void AdBlockSubscriptionServiceManager::ClearSubscriptionPrefs( const GURL& sub_url) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - PrefService* local_state = delegate_->local_state(); - if (!local_state) + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!local_state_) return; - DictionaryPrefUpdate update(local_state, prefs::kAdBlockListSubscriptions); + DictionaryPrefUpdate update(local_state_, prefs::kAdBlockListSubscriptions); base::Value* subscriptions_dict = update.Get(); subscriptions_dict->RemoveKey(sub_url.spec()); @@ -355,10 +429,6 @@ void AdBlockSubscriptionServiceManager::ClearSubscriptionPrefs( } bool AdBlockSubscriptionServiceManager::Start() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - for (const auto& subscription_service : subscription_services_) { - subscription_service.second->Start(); - } return true; } @@ -387,7 +457,7 @@ void AdBlockSubscriptionServiceManager::ShouldStartRequest( void AdBlockSubscriptionServiceManager::EnableTag(const std::string& tag, bool enabled) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (const auto& subscription_service : subscription_services_) { subscription_service.second->EnableTag(tag, enabled); } @@ -395,7 +465,7 @@ void AdBlockSubscriptionServiceManager::EnableTag(const std::string& tag, void AdBlockSubscriptionServiceManager::AddResources( const std::string& resources) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (const auto& subscription_service : subscription_services_) { subscription_service.second->AddResources(resources); } @@ -453,9 +523,10 @@ base::Value AdBlockSubscriptionServiceManager::HiddenClassIdSelectors( void AdBlockSubscriptionServiceManager::OnSubscriptionDownloaded( const GURL& sub_url) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - auto it = subscription_services_.find(sub_url); - if (it == subscription_services_.end()) + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto subscription_filters_provider = + subscription_filters_providers_.find(sub_url); + if (subscription_filters_provider == subscription_filters_providers_.end()) return; auto info = GetInfo(sub_url); @@ -466,7 +537,12 @@ void AdBlockSubscriptionServiceManager::OnSubscriptionDownloaded( info->last_successful_update_attempt = info->last_update_attempt; UpdateSubscriptionPrefs(sub_url, *info); - it->second->ReloadList(); + auto subscription_source_observer = + subscription_source_observers_.find(sub_url); + DCHECK(subscription_source_observer != subscription_source_observers_.end()); + + subscription_filters_provider->second->LoadDAT( + (subscription_source_observer->second).get()); NotifyObserversOfServiceEvent(); } diff --git a/components/brave_shields/browser/ad_block_subscription_service_manager.h b/components/brave_shields/browser/ad_block_subscription_service_manager.h index 9931bb6e1396..f6e60df3e26c 100644 --- a/components/brave_shields/browser/ad_block_subscription_service_manager.h +++ b/components/brave_shields/browser/ad_block_subscription_service_manager.h @@ -15,21 +15,31 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/one_shot_event.h" +#include "base/sequence_checker.h" #include "base/synchronization/lock.h" -#include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "base/values.h" #include "brave/components/brave_component_updater/browser/brave_component.h" +#include "brave/components/brave_shields/browser/ad_block_engine.h" +#include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_subscription_download_manager.h" -#include "brave/components/brave_shields/browser/ad_block_subscription_service.h" #include "components/component_updater/timer_update_scheduler.h" +#include "components/prefs/pref_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" class PrefService; +namespace base { +template +class JSONValueConverter; +} + namespace brave_shields { +class AdBlockResourceProvider; class AdBlockSubscriptionServiceManagerObserver; -} +class AdBlockSubscriptionFiltersProvider; +} // namespace brave_shields class AdBlockServiceTest; @@ -37,12 +47,33 @@ using brave_component_updater::BraveComponent; namespace brave_shields { +struct SubscriptionInfo { + // The URL used to fetch the list, which is also used as a unique identifier + // for a subscription service. + GURL subscription_url; + + // These are base::Time::Min() if no download has been + // attempted/succeeded. If a subscription has been successfully downloaded, + // both of these are exactly equal. + base::Time last_update_attempt; + base::Time last_successful_update_attempt; + + // Any enabled list will be queried during network requests and page loads, + // otherwise it will be bypassed. Disabled lists will not be automatically + // updated. + bool enabled; + + static void RegisterJSONConverter( + base::JSONValueConverter*); +}; + // The AdBlock subscription service manager, in charge of initializing and // managing AdBlock clients corresponding to custom filter list subscriptions. class AdBlockSubscriptionServiceManager { public: explicit AdBlockSubscriptionServiceManager( - BraveComponent::Delegate* delegate, + PrefService* local_state, + scoped_refptr task_runner, AdBlockSubscriptionDownloadManager::DownloadManagerGetter getter, const base::FilePath& profile_dir); ~AdBlockSubscriptionServiceManager(); @@ -85,6 +116,9 @@ class AdBlockSubscriptionServiceManager { void AddObserver(AdBlockSubscriptionServiceManagerObserver* observer); void RemoveObserver(AdBlockSubscriptionServiceManagerObserver* observer); + void Init(AdBlockResourceProvider* resource_provider); + bool IsInitialized(); + private: friend class ::AdBlockServiceTest; // Returns the directory used to store cached list data for the given @@ -96,7 +130,7 @@ class AdBlockSubscriptionServiceManager { void StartDownload(const GURL& sub_url, bool from_ui); - bool Init(); + bool initialized_; void LoadSubscriptionServices(); void UpdateSubscriptionPrefs(const GURL& sub_url, const SubscriptionInfo& info); @@ -110,21 +144,28 @@ class AdBlockSubscriptionServiceManager { void SetUpdateIntervalsForTesting(base::TimeDelta* initial_delay, base::TimeDelta* retry_interval); - raw_ptr delegate_ = - nullptr; // NOT OWNED + raw_ptr local_state_; + scoped_refptr task_runner_; + raw_ptr resource_provider_; + raw_ptr + delegate_; // NOT OWNED base::WeakPtr download_manager_; base::FilePath subscription_path_; std::unique_ptr subscriptions_; - std::map> + std::map> subscription_services_; + std::map> + subscription_filters_providers_; + std::map> + subscription_source_observers_; std::unique_ptr subscription_update_timer_; base::ObserverList observers_; base::Lock subscription_services_lock_; - THREAD_CHECKER(thread_checker_); + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory weak_ptr_factory_{ this}; diff --git a/components/brave_shields/browser/base_brave_shields_service.cc b/components/brave_shields/browser/base_brave_shields_service.cc index 57faa8a36b67..93819a7111a6 100644 --- a/components/brave_shields/browser/base_brave_shields_service.cc +++ b/components/brave_shields/browser/base_brave_shields_service.cc @@ -15,15 +15,11 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" -using brave_component_updater::BraveComponent; - namespace brave_shields { BaseBraveShieldsService::BaseBraveShieldsService( - BraveComponent::Delegate* delegate) - : BraveComponent(delegate), - initialized_(false) { -} + scoped_refptr task_runner) + : initialized_(false), task_runner_(task_runner) {} BaseBraveShieldsService::~BaseBraveShieldsService() { } @@ -58,4 +54,9 @@ void BaseBraveShieldsService::ShouldStartRequest( bool* did_match_important, std::string* mock_data_url) {} +scoped_refptr +BaseBraveShieldsService::GetTaskRunner() { + return task_runner_; +} + } // namespace brave_shields diff --git a/components/brave_shields/browser/base_brave_shields_service.h b/components/brave_shields/browser/base_brave_shields_service.h index 781d5e3e5555..0fb0cb361242 100644 --- a/components/brave_shields/browser/base_brave_shields_service.h +++ b/components/brave_shields/browser/base_brave_shields_service.h @@ -25,10 +25,11 @@ namespace brave_shields { // The brave shields service in charge of checking brave shields like ad-block, // tracking protection, etc. -class BaseBraveShieldsService : public BraveComponent { +class BaseBraveShieldsService { public: - explicit BaseBraveShieldsService(BraveComponent::Delegate* delegate); - ~BaseBraveShieldsService() override; + explicit BaseBraveShieldsService( + scoped_refptr task_runner); + virtual ~BaseBraveShieldsService(); bool Start(); bool IsInitialized() const; virtual void ShouldStartRequest(const GURL& url, @@ -40,6 +41,8 @@ class BaseBraveShieldsService : public BraveComponent { bool* did_match_important, std::string* mock_data_url); + scoped_refptr GetTaskRunner(); + protected: virtual bool Init() = 0; diff --git a/components/brave_shields/browser/domain_block_controller_client.cc b/components/brave_shields/browser/domain_block_controller_client.cc index d0c57461e2ac..3f7ce33da83f 100644 --- a/components/brave_shields/browser/domain_block_controller_client.cc +++ b/components/brave_shields/browser/domain_block_controller_client.cc @@ -5,7 +5,7 @@ #include "brave/components/brave_shields/browser/domain_block_controller_client.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" +#include "brave/components/brave_shields/browser/ad_block_custom_filters_provider.h" #include "brave/components/brave_shields/browser/domain_block_tab_storage.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/content/settings_page_helper.h" @@ -31,7 +31,7 @@ DomainBlockControllerClient::GetMetricsHelper(const GURL& url) { DomainBlockControllerClient::DomainBlockControllerClient( content::WebContents* web_contents, const GURL& request_url, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, PrefService* prefs, const std::string& locale) @@ -43,7 +43,7 @@ DomainBlockControllerClient::DomainBlockControllerClient( GURL("about:blank") /* default_safe_page */, nullptr /* settings_page_helper */), request_url_(request_url), - ad_block_custom_filters_service_(ad_block_custom_filters_service), + ad_block_custom_filters_provider_(ad_block_custom_filters_provider), ephemeral_storage_service_(ephemeral_storage_service), dont_warn_again_(false) {} @@ -59,8 +59,8 @@ void DomainBlockControllerClient::Proceed() { tab_storage->SetIsProceeding(true); if (dont_warn_again_) { std::string custom_filters = - ad_block_custom_filters_service_->GetCustomFilters(); - ad_block_custom_filters_service_->UpdateCustomFilters( + ad_block_custom_filters_provider_->GetCustomFilters(); + ad_block_custom_filters_provider_->UpdateCustomFilters( "@@||" + request_url_.host() + "^\n" + custom_filters); } diff --git a/components/brave_shields/browser/domain_block_controller_client.h b/components/brave_shields/browser/domain_block_controller_client.h index 0c5e86bbb972..c27ac9db4cf4 100644 --- a/components/brave_shields/browser/domain_block_controller_client.h +++ b/components/brave_shields/browser/domain_block_controller_client.h @@ -28,7 +28,7 @@ class EphemeralStorageService; namespace brave_shields { -class AdBlockCustomFiltersService; +class AdBlockCustomFiltersProvider; class DomainBlockControllerClient : public security_interstitials::SecurityInterstitialControllerClient { @@ -39,7 +39,7 @@ class DomainBlockControllerClient DomainBlockControllerClient( content::WebContents* web_contents, const GURL& request_url, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, PrefService* prefs, const std::string& locale); @@ -60,7 +60,7 @@ class DomainBlockControllerClient void OnCanEnable1PESForUrl(bool can_enable_1pes); const GURL request_url_; - raw_ptr ad_block_custom_filters_service_ = + raw_ptr ad_block_custom_filters_provider_ = nullptr; raw_ptr ephemeral_storage_service_ = nullptr; diff --git a/components/brave_shields/browser/domain_block_navigation_throttle.cc b/components/brave_shields/browser/domain_block_navigation_throttle.cc index 918da3732e99..124d3e05fa7d 100644 --- a/components/brave_shields/browser/domain_block_navigation_throttle.cc +++ b/components/brave_shields/browser/domain_block_navigation_throttle.cc @@ -13,7 +13,6 @@ #include "base/metrics/histogram_macros.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" -#include "brave/components/brave_shields/browser/ad_block_custom_filters_service.h" #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/domain_block_controller_client.h" #include "brave/components/brave_shields/browser/domain_block_page.h" @@ -60,11 +59,11 @@ std::unique_ptr DomainBlockNavigationThrottle::MaybeCreateThrottleFor( content::NavigationHandle* navigation_handle, AdBlockService* ad_block_service, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, HostContentSettingsMap* content_settings, const std::string& locale) { - if (!ad_block_service || !ad_block_custom_filters_service) + if (!ad_block_service || !ad_block_custom_filters_provider) return nullptr; if (!base::FeatureList::IsEnabled(brave_shields::features::kBraveDomainBlock)) return nullptr; @@ -72,20 +71,20 @@ DomainBlockNavigationThrottle::MaybeCreateThrottleFor( if (!navigation_handle->IsInMainFrame()) return nullptr; return std::make_unique( - navigation_handle, ad_block_service, ad_block_custom_filters_service, + navigation_handle, ad_block_service, ad_block_custom_filters_provider, ephemeral_storage_service, content_settings, locale); } DomainBlockNavigationThrottle::DomainBlockNavigationThrottle( content::NavigationHandle* navigation_handle, AdBlockService* ad_block_service, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, HostContentSettingsMap* content_settings, const std::string& locale) : content::NavigationThrottle(navigation_handle), ad_block_service_(ad_block_service), - ad_block_custom_filters_service_(ad_block_custom_filters_service), + ad_block_custom_filters_provider_(ad_block_custom_filters_provider), ephemeral_storage_service_(ephemeral_storage_service), content_settings_(content_settings), locale_(locale) { @@ -100,9 +99,6 @@ content::NavigationThrottle::ThrottleCheckResult DomainBlockNavigationThrottle::WillStartRequest() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!ad_block_service_->IsInitialized()) - return content::NavigationThrottle::PROCEED; - content::NavigationHandle* handle = navigation_handle(); DCHECK(handle->IsInMainFrame()); GURL request_url = handle->GetURL(); @@ -195,7 +191,7 @@ void DomainBlockNavigationThrottle::ShowInterstitial() { // The controller client implements the actual logic to "go back" or "proceed" // from the interstitial. auto controller_client = std::make_unique( - web_contents, request_url, ad_block_custom_filters_service_, + web_contents, request_url, ad_block_custom_filters_provider_, ephemeral_storage_service_, pref_service, locale_); // This handles populating the HTML template of the interstitial page with diff --git a/components/brave_shields/browser/domain_block_navigation_throttle.h b/components/brave_shields/browser/domain_block_navigation_throttle.h index a8b228d24c66..90ac0015e1c6 100644 --- a/components/brave_shields/browser/domain_block_navigation_throttle.h +++ b/components/brave_shields/browser/domain_block_navigation_throttle.h @@ -29,14 +29,14 @@ class EphemeralStorageService; namespace brave_shields { class AdBlockService; -class AdBlockCustomFiltersService; +class AdBlockCustomFiltersProvider; class DomainBlockNavigationThrottle : public content::NavigationThrottle { public: explicit DomainBlockNavigationThrottle( content::NavigationHandle* navigation_handle, AdBlockService* ad_block_service, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, HostContentSettingsMap* content_settings, const std::string& locale); @@ -49,7 +49,7 @@ class DomainBlockNavigationThrottle : public content::NavigationThrottle { static std::unique_ptr MaybeCreateThrottleFor( content::NavigationHandle* navigation_handle, AdBlockService* ad_block_service, - AdBlockCustomFiltersService* ad_block_custom_filters_service, + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider, ephemeral_storage::EphemeralStorageService* ephemeral_storage_service, HostContentSettingsMap* content_settings, const std::string& locale); @@ -68,7 +68,7 @@ class DomainBlockNavigationThrottle : public content::NavigationThrottle { void Enable1PESAndResume(); AdBlockService* ad_block_service_ = nullptr; - AdBlockCustomFiltersService* ad_block_custom_filters_service_ = nullptr; + AdBlockCustomFiltersProvider* ad_block_custom_filters_provider_ = nullptr; ephemeral_storage::EphemeralStorageService* ephemeral_storage_service_ = nullptr; HostContentSettingsMap* content_settings_ = nullptr; diff --git a/components/brave_shields/browser/https_everywhere_component_installer.cc b/components/brave_shields/browser/https_everywhere_component_installer.cc new file mode 100644 index 000000000000..108d61bba0fb --- /dev/null +++ b/components/brave_shields/browser/https_everywhere_component_installer.cc @@ -0,0 +1,167 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/https_everywhere_component_installer.h" + +#include +#include +#include + +#include "base/base64.h" +#include "base/bind.h" +#include "base/callback.h" +#include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h" +#include "components/component_updater/component_installer.h" +#include "components/component_updater/component_updater_service.h" +#include "crypto/sha2.h" + +using brave_component_updater::BraveOnDemandUpdater; + +namespace brave_shields { + +namespace { + +constexpr size_t kHashSize = 32; +const char kHTTPSEverywhereComponentName[] = "Brave HTTPS Everywhere Updater"; +const char kHTTPSEverywhereComponentId[] = "oofiananboodjbbmdelgdommihjbkfag"; +const char kHTTPSEverywhereComponentBase64PublicKey[] = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvn9zSMjTmhkQyrZu5UdN" + "350nPqLoSeCYngcC7yDFwaUHjoBQXCZqGeDC69ciCQ2mlRhcV2nxXqlUDkiC6+7m" + "651nI+gi4oVqHagc7EFUyGA0yuIk7qIMvCBdH7wbET27de0rzbRzRht9EKzEjIhC" + "BtoPnmyrO/8qPrH4XR4cPfnFPuJssBBxC1B35H7rh0Br9qePhPDDe9OjyqYxPuio" + "+YcC9obL4g5krVrfrlKLfFNpIewUcJyBpSlCgfxEyEhgDkK9cILTMUi5vC7GxS3P" + "OtZqgfRg8Da4i+NwmjQqrz0JFtPMMSyUnmeMj+mSOL4xZVWr8fU2/GOCXs9gczDp" + "JwIDAQAB"; + +class HTTPSEverywhereComponentInstallerPolicy + : public component_updater::ComponentInstallerPolicy { + public: + explicit HTTPSEverywhereComponentInstallerPolicy( + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback); + ~HTTPSEverywhereComponentInstallerPolicy() override; + + HTTPSEverywhereComponentInstallerPolicy( + const HTTPSEverywhereComponentInstallerPolicy&) = delete; + HTTPSEverywhereComponentInstallerPolicy& operator=( + const HTTPSEverywhereComponentInstallerPolicy&) = delete; + + // component_updater::ComponentInstallerPolicy + bool SupportsGroupPolicyEnabledComponentUpdates() const override; + bool RequiresNetworkEncryption() const override; + update_client::CrxInstaller::Result OnCustomInstall( + const base::DictionaryValue& manifest, + const base::FilePath& install_dir) override; + void OnCustomUninstall() override; + bool VerifyInstallation(const base::DictionaryValue& manifest, + const base::FilePath& install_dir) const override; + void ComponentReady(const base::Version& version, + const base::FilePath& path, + std::unique_ptr manifest) override; + base::FilePath GetRelativeInstallDir() const override; + void GetHash(std::vector* hash) const override; + std::string GetName() const override; + update_client::InstallerAttributes GetInstallerAttributes() const override; + + private: + const std::string component_id_; + const std::string component_name_; + OnComponentReadyCallback ready_callback_; + uint8_t component_hash_[kHashSize]; +}; + +HTTPSEverywhereComponentInstallerPolicy:: + HTTPSEverywhereComponentInstallerPolicy( + const std::string& component_public_key, + const std::string& component_id, + const std::string& component_name, + OnComponentReadyCallback callback) + : component_id_(component_id), + component_name_(component_name), + ready_callback_(callback) { + // Generate hash from public key. + std::string decoded_public_key; + base::Base64Decode(component_public_key, &decoded_public_key); + crypto::SHA256HashString(decoded_public_key, component_hash_, kHashSize); +} + +HTTPSEverywhereComponentInstallerPolicy:: + ~HTTPSEverywhereComponentInstallerPolicy() = default; + +bool HTTPSEverywhereComponentInstallerPolicy:: + SupportsGroupPolicyEnabledComponentUpdates() const { + return true; +} + +bool HTTPSEverywhereComponentInstallerPolicy::RequiresNetworkEncryption() + const { + return false; +} + +update_client::CrxInstaller::Result +HTTPSEverywhereComponentInstallerPolicy::OnCustomInstall( + const base::DictionaryValue& manifest, + const base::FilePath& install_dir) { + return update_client::CrxInstaller::Result(0); +} + +void HTTPSEverywhereComponentInstallerPolicy::OnCustomUninstall() {} + +void HTTPSEverywhereComponentInstallerPolicy::ComponentReady( + const base::Version& version, + const base::FilePath& path, + std::unique_ptr manifest) { + ready_callback_.Run(path); +} + +bool HTTPSEverywhereComponentInstallerPolicy::VerifyInstallation( + const base::DictionaryValue& manifest, + const base::FilePath& install_dir) const { + return true; +} + +base::FilePath HTTPSEverywhereComponentInstallerPolicy::GetRelativeInstallDir() + const { + return base::FilePath::FromUTF8Unsafe(component_id_); +} + +void HTTPSEverywhereComponentInstallerPolicy::GetHash( + std::vector* hash) const { + hash->assign(component_hash_, component_hash_ + kHashSize); +} + +std::string HTTPSEverywhereComponentInstallerPolicy::GetName() const { + return component_name_; +} + +update_client::InstallerAttributes +HTTPSEverywhereComponentInstallerPolicy::GetInstallerAttributes() const { + return update_client::InstallerAttributes(); +} + +void OnRegistered(const std::string& component_id) { + BraveOnDemandUpdater::GetInstance()->OnDemandUpdate(component_id); +} + +} // namespace + +void RegisterHTTPSEverywhereComponent( + component_updater::ComponentUpdateService* cus, + OnComponentReadyCallback callback) { + // In test, |cus| could be nullptr. + if (!cus) + return; + + auto installer = base::MakeRefCounted( + std::make_unique( + kHTTPSEverywhereComponentBase64PublicKey, kHTTPSEverywhereComponentId, + kHTTPSEverywhereComponentName, callback)); + installer->Register( + cus, base::BindOnce(&OnRegistered, kHTTPSEverywhereComponentId)); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/https_everywhere_component_installer.h b/components/brave_shields/browser/https_everywhere_component_installer.h new file mode 100644 index 000000000000..bcee4ec6875b --- /dev/null +++ b/components/brave_shields/browser/https_everywhere_component_installer.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ + +#include + +#include "base/callback.h" +#include "base/files/file_path.h" + +namespace component_updater { +class ComponentUpdateService; +} // namespace component_updater + +namespace brave_shields { + +using OnComponentReadyCallback = + base::RepeatingCallback; + +void RegisterHTTPSEverywhereComponent( + component_updater::ComponentUpdateService* cus, + OnComponentReadyCallback callback); + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_HTTPS_EVERYWHERE_COMPONENT_INSTALLER_H_ diff --git a/components/brave_shields/browser/https_everywhere_service.cc b/components/brave_shields/browser/https_everywhere_service.cc index b8d866e827dc..28822f42ce72 100644 --- a/components/brave_shields/browser/https_everywhere_service.cc +++ b/components/brave_shields/browser/https_everywhere_service.cc @@ -79,46 +79,15 @@ std::string leveldbGet(leveldb::DB* db, const std::string &key) { namespace brave_shields { -const char kHTTPSEverywhereComponentName[] = "Brave HTTPS Everywhere Updater"; -const char kHTTPSEverywhereComponentId[] = "oofiananboodjbbmdelgdommihjbkfag"; -const char kHTTPSEverywhereComponentBase64PublicKey[] = - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvn9zSMjTmhkQyrZu5UdN" - "350nPqLoSeCYngcC7yDFwaUHjoBQXCZqGeDC69ciCQ2mlRhcV2nxXqlUDkiC6+7m" - "651nI+gi4oVqHagc7EFUyGA0yuIk7qIMvCBdH7wbET27de0rzbRzRht9EKzEjIhC" - "BtoPnmyrO/8qPrH4XR4cPfnFPuJssBBxC1B35H7rh0Br9qePhPDDe9OjyqYxPuio" - "+YcC9obL4g5krVrfrlKLfFNpIewUcJyBpSlCgfxEyEhgDkK9cILTMUi5vC7GxS3P" - "OtZqgfRg8Da4i+NwmjQqrz0JFtPMMSyUnmeMj+mSOL4xZVWr8fU2/GOCXs9gczDp" - "JwIDAQAB"; - -bool HTTPSEverywhereService::g_ignore_port_for_test_(false); -std::string HTTPSEverywhereService::g_https_everywhere_component_id_( - kHTTPSEverywhereComponentId); -std::string -HTTPSEverywhereService::g_https_everywhere_component_base64_public_key_( - kHTTPSEverywhereComponentBase64PublicKey); - -HTTPSEverywhereService::HTTPSEverywhereService( - BraveComponent::Delegate* delegate) - : BaseBraveShieldsService(delegate), - level_db_(nullptr) { +HTTPSEverywhereService::Engine::Engine(HTTPSEverywhereService* service) + : level_db_(nullptr), service_(service) { DETACH_FROM_SEQUENCE(sequence_checker_); } -HTTPSEverywhereService::~HTTPSEverywhereService() { - GetTaskRunner()->DeleteSoon(FROM_HERE, level_db_); -} - -bool HTTPSEverywhereService::Init() { - Register(kHTTPSEverywhereComponentName, - g_https_everywhere_component_id_, - g_https_everywhere_component_base64_public_key_); - return true; -} - -void HTTPSEverywhereService::InitDB(const base::FilePath& install_dir) { +void HTTPSEverywhereService::Engine::Init(const base::FilePath& base_dir) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::FilePath zip_db_file_path = - install_dir.AppendASCII(DAT_FILE_VERSION).AppendASCII(DAT_FILE); + base_dir.AppendASCII(DAT_FILE_VERSION).AppendASCII(DAT_FILE); base::FilePath unzipped_level_db_path = zip_db_file_path.RemoveExtension(); base::FilePath destination = zip_db_file_path.DirName(); if (!zip::Unzip(zip_db_file_path, destination)) { @@ -143,16 +112,7 @@ void HTTPSEverywhereService::InitDB(const base::FilePath& install_dir) { } } -void HTTPSEverywhereService::OnComponentReady( - const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) { - GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&HTTPSEverywhereService::InitDB, AsWeakPtr(), - install_dir)); -} - -bool HTTPSEverywhereService::GetHTTPSURL( +bool HTTPSEverywhereService::Engine::GetHTTPSURL( const GURL* url, const uint64_t& request_identifier, std::string* new_url) { @@ -161,15 +121,16 @@ bool HTTPSEverywhereService::GetHTTPSURL( if (!url->is_valid()) return false; - if (!IsInitialized() || !level_db_ || url->scheme() == url::kHttpsScheme) { + if (!level_db_ || url->scheme() == url::kHttpsScheme) { return false; } - if (!ShouldHTTPSERedirect(request_identifier)) { + + if (!service_->ShouldHTTPSERedirect(request_identifier)) { return false; } - if (recently_used_cache_.get(url->spec(), new_url)) { - AddHTTPSEUrlToRedirectList(request_identifier); + if (service_->recently_used_cache().get(url->spec(), new_url)) { + service_->AddHTTPSEUrlToRedirectList(request_identifier); return true; } @@ -188,80 +149,17 @@ bool HTTPSEverywhereService::GetHTTPSURL( if (!value.empty()) { *new_url = ApplyHTTPSRule(candidate_url.spec(), value); if (0 != new_url->length()) { - recently_used_cache_.add(candidate_url.spec(), *new_url); - AddHTTPSEUrlToRedirectList(request_identifier); + service_->recently_used_cache().add(candidate_url.spec(), *new_url); + service_->AddHTTPSEUrlToRedirectList(request_identifier); return true; } } } - recently_used_cache_.remove(candidate_url.spec()); - return false; -} - -bool HTTPSEverywhereService::GetHTTPSURLFromCacheOnly( - const GURL* url, - const uint64_t& request_identifier, - std::string* cached_url) { - if (!url->is_valid()) - return false; - - if (!IsInitialized() || url->scheme() == url::kHttpsScheme) { - return false; - } - if (!ShouldHTTPSERedirect(request_identifier)) { - return false; - } - - if (recently_used_cache_.get(url->spec(), cached_url)) { - AddHTTPSEUrlToRedirectList(request_identifier); - return true; - } + service_->recently_used_cache().remove(candidate_url.spec()); return false; } -bool HTTPSEverywhereService::ShouldHTTPSERedirect( - const uint64_t& request_identifier) { - base::AutoLock auto_lock(httpse_get_urls_redirects_count_mutex_); - for (size_t i = 0; i < httpse_urls_redirects_count_.size(); i++) { - if (request_identifier == - httpse_urls_redirects_count_[i].request_identifier_ && - httpse_urls_redirects_count_[i].redirects_ >= - HTTPSE_URL_MAX_REDIRECTS_COUNT - 1) { - return false; - } - } - - return true; -} - -void HTTPSEverywhereService::AddHTTPSEUrlToRedirectList( - const uint64_t& request_identifier) { - // Adding redirects count for the current request - base::AutoLock auto_lock(httpse_get_urls_redirects_count_mutex_); - bool hostFound = false; - for (size_t i = 0; i < httpse_urls_redirects_count_.size(); i++) { - if (request_identifier == - httpse_urls_redirects_count_[i].request_identifier_) { - // Found the host, just increment the redirects_count - httpse_urls_redirects_count_[i].redirects_++; - hostFound = true; - break; - } - } - if (!hostFound) { - // The host is new, adding it to the redirects list - if (httpse_urls_redirects_count_.size() >= - HTTPSE_URLS_REDIRECTS_COUNT_QUEUE) { - // The queue is full, erase the first element - httpse_urls_redirects_count_.erase( - httpse_urls_redirects_count_.begin()); - } - httpse_urls_redirects_count_.push_back( - HTTPSE_REDIRECTS_COUNT_ST(request_identifier, 1)); - } -} - -std::string HTTPSEverywhereService::ApplyHTTPSRule( +std::string HTTPSEverywhereService::Engine::ApplyHTTPSRule( const std::string& originalUrl, const std::string& rule) { absl::optional json_object = base::JSONReader::Read(rule); @@ -361,7 +259,7 @@ std::string HTTPSEverywhereService::ApplyHTTPSRule( return ""; } -std::string HTTPSEverywhereService::CorrecttoRuleToRE2Engine( +std::string HTTPSEverywhereService::Engine::CorrecttoRuleToRE2Engine( const std::string& to) { std::string correctedto(to); size_t pos = to.find("$"); @@ -373,7 +271,7 @@ std::string HTTPSEverywhereService::CorrecttoRuleToRE2Engine( return correctedto; } -void HTTPSEverywhereService::CloseDatabase() { +void HTTPSEverywhereService::Engine::CloseDatabase() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (level_db_) { delete level_db_; @@ -381,12 +279,94 @@ void HTTPSEverywhereService::CloseDatabase() { } } -// static -void HTTPSEverywhereService::SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key) { - g_https_everywhere_component_id_ = component_id; - g_https_everywhere_component_base64_public_key_ = component_base64_public_key; +bool HTTPSEverywhereService::g_ignore_port_for_test_(false); + +HTTPSEverywhereService::HTTPSEverywhereService( + scoped_refptr task_runner) + : BaseBraveShieldsService(task_runner), + engine_(new Engine(this), base::OnTaskRunnerDeleter(task_runner)) {} + +HTTPSEverywhereService::~HTTPSEverywhereService() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +bool HTTPSEverywhereService::Init() { + return true; +} + +void HTTPSEverywhereService::InitDB(const base::FilePath& install_dir) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + GetTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&Engine::Init, engine_->AsWeakPtr(), install_dir)); +} + +bool HTTPSEverywhereService::GetHTTPSURLFromCacheOnly( + const GURL* url, + const uint64_t& request_identifier, + std::string* cached_url) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!url->is_valid()) + return false; + + if (!IsInitialized() || url->scheme() == url::kHttpsScheme) { + return false; + } + if (!ShouldHTTPSERedirect(request_identifier)) { + return false; + } + + if (recently_used_cache_.get(url->spec(), cached_url)) { + AddHTTPSEUrlToRedirectList(request_identifier); + return true; + } + return false; +} + +HTTPSERecentlyUsedCache& +HTTPSEverywhereService::recently_used_cache() { + return recently_used_cache_; +} + +bool HTTPSEverywhereService::ShouldHTTPSERedirect( + const uint64_t& request_identifier) { + base::AutoLock auto_lock(httpse_get_urls_redirects_count_mutex_); + for (size_t i = 0; i < httpse_urls_redirects_count_.size(); i++) { + if (request_identifier == + httpse_urls_redirects_count_[i].request_identifier_ && + httpse_urls_redirects_count_[i].redirects_ >= + HTTPSE_URL_MAX_REDIRECTS_COUNT - 1) { + return false; + } + } + + return true; +} + +void HTTPSEverywhereService::AddHTTPSEUrlToRedirectList( + const uint64_t& request_identifier) { + // Adding redirects count for the current request + base::AutoLock auto_lock(httpse_get_urls_redirects_count_mutex_); + bool hostFound = false; + for (size_t i = 0; i < httpse_urls_redirects_count_.size(); i++) { + if (request_identifier == + httpse_urls_redirects_count_[i].request_identifier_) { + // Found the host, just increment the redirects_count + httpse_urls_redirects_count_[i].redirects_++; + hostFound = true; + break; + } + } + if (!hostFound) { + // The host is new, adding it to the redirects list + if (httpse_urls_redirects_count_.size() >= + HTTPSE_URLS_REDIRECTS_COUNT_QUEUE) { + // The queue is full, erase the first element + httpse_urls_redirects_count_.erase(httpse_urls_redirects_count_.begin()); + } + httpse_urls_redirects_count_.push_back( + HTTPSE_REDIRECTS_COUNT_ST(request_identifier, 1)); + } } // static @@ -399,8 +379,8 @@ void HTTPSEverywhereService::SetIgnorePortForTest(bool ignore) { // The brave shields factory. Using the Brave Shields as a singleton // is the job of the browser process. std::unique_ptr HTTPSEverywhereServiceFactory( - BraveComponent::Delegate* delegate) { - return std::make_unique(delegate); + scoped_refptr task_runner) { + return std::make_unique(task_runner); } } // namespace brave_shields diff --git a/components/brave_shields/browser/https_everywhere_service.h b/components/brave_shields/browser/https_everywhere_service.h index a0309cd84b3d..a227d5ce6fef 100644 --- a/components/brave_shields/browser/https_everywhere_service.h +++ b/components/brave_shields/browser/https_everywhere_service.h @@ -43,57 +43,68 @@ struct HTTPSE_REDIRECTS_COUNT_ST { unsigned int redirects_; }; -class HTTPSEverywhereService : public BaseBraveShieldsService, - public base::SupportsWeakPtr { +class HTTPSEverywhereService : public BaseBraveShieldsService { public: - explicit HTTPSEverywhereService(BraveComponent::Delegate* delegate); + explicit HTTPSEverywhereService( + scoped_refptr task_runner); HTTPSEverywhereService(const HTTPSEverywhereService&) = delete; HTTPSEverywhereService& operator=(const HTTPSEverywhereService&) = delete; ~HTTPSEverywhereService() override; - bool GetHTTPSURL(const GURL* url, - const uint64_t& request_id, - std::string* new_url); + + class Engine : public base::SupportsWeakPtr { + public: + explicit Engine(HTTPSEverywhereService* service); + Engine(const Engine&) = delete; + Engine& operator=(const Engine&) = delete; + + void Init(const base::FilePath& base_dir); + bool GetHTTPSURL(const GURL* url, + const uint64_t& request_id, + std::string* new_url); + + private: + std::string ApplyHTTPSRule(const std::string& originalUrl, + const std::string& rule); + std::string CorrecttoRuleToRE2Engine(const std::string& to); + void CloseDatabase(); + + leveldb::DB* level_db_; + HTTPSEverywhereService* service_; // not owned + SEQUENCE_CHECKER(sequence_checker_); + }; + + void InitDB(const base::FilePath& install_dir); + bool GetHTTPSURLFromCacheOnly(const GURL* url, const uint64_t& request_id, std::string* cached_url); + base::WeakPtr engine() { return engine_->AsWeakPtr(); } + protected: bool Init() override; - void OnComponentReady(const std::string& component_id, - const base::FilePath& install_dir, - const std::string& manifest) override; - - void AddHTTPSEUrlToRedirectList(const uint64_t& request_id); - bool ShouldHTTPSERedirect(const uint64_t& request_id); - std::string ApplyHTTPSRule(const std::string& originalUrl, - const std::string& rule); - std::string CorrecttoRuleToRE2Engine(const std::string& to); private: friend class ::HTTPSEverywhereServiceTest; + friend class Engine; static bool g_ignore_port_for_test_; - static std::string g_https_everywhere_component_id_; - static std::string g_https_everywhere_component_base64_public_key_; static void SetIgnorePortForTest(bool ignore); - static void SetComponentIdAndBase64PublicKeyForTest( - const std::string& component_id, - const std::string& component_base64_public_key); - - void CloseDatabase(); - void InitDB(const base::FilePath& install_dir); + void AddHTTPSEUrlToRedirectList(const uint64_t& request_id); + bool ShouldHTTPSERedirect(const uint64_t& request_id); + HTTPSERecentlyUsedCache& recently_used_cache(); base::Lock httpse_get_urls_redirects_count_mutex_; std::vector httpse_urls_redirects_count_; HTTPSERecentlyUsedCache recently_used_cache_; - leveldb::DB* level_db_; + std::unique_ptr engine_; SEQUENCE_CHECKER(sequence_checker_); }; // Creates the HTTPSEverywhereService std::unique_ptr HTTPSEverywhereServiceFactory( - BraveComponent::Delegate* delegate); + scoped_refptr task_runner); } // namespace brave_shields diff --git a/components/brave_shields/browser/https_everywhere_service_browsertest.cc b/components/brave_shields/browser/https_everywhere_service_browsertest.cc index 87283f289cf3..3da1ad9ff24a 100644 --- a/components/brave_shields/browser/https_everywhere_service_browsertest.cc +++ b/components/brave_shields/browser/https_everywhere_service_browsertest.cc @@ -7,6 +7,7 @@ #include "base/task/post_task.h" #include "base/test/thread_test_helper.h" #include "brave/browser/brave_browser_process.h" +#include "brave/browser/brave_shields/https_everywhere_component_installer.h" #include "brave/common/brave_paths.h" #include "brave/components/brave_shields/browser/https_everywhere_service.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -63,10 +64,9 @@ class HTTPSEverywhereServiceTest : public ExtensionBrowserTest { void InitService() { brave_shields::HTTPSEverywhereService::SetIgnorePortForTest(true); - brave_shields::HTTPSEverywhereService:: - SetComponentIdAndBase64PublicKeyForTest( - kHTTPSEverywhereComponentTestId, - kHTTPSEverywhereComponentTestBase64PublicKey); + brave_shields::SetHTTPSEverywhereComponentIdAndBase64PublicKeyForTest( + kHTTPSEverywhereComponentTestId, + kHTTPSEverywhereComponentTestBase64PublicKey); } void GetTestDataDir(base::FilePath* test_data_dir) { @@ -82,8 +82,8 @@ class HTTPSEverywhereServiceTest : public ExtensionBrowserTest { if (!httpse_extension) return false; - g_brave_browser_process->https_everywhere_service()->OnComponentReady( - httpse_extension->id(), httpse_extension->path(), ""); + g_brave_browser_process->https_everywhere_service()->InitDB( + httpse_extension->path()); WaitForHTTPSEverywhereServiceThread(); return true; diff --git a/components/brave_shields/browser/test_filters_provider.cc b/components/brave_shields/browser/test_filters_provider.cc new file mode 100644 index 000000000000..2d191d07a24c --- /dev/null +++ b/components/brave_shields/browser/test_filters_provider.cc @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/components/brave_shields/browser/test_filters_provider.h" + +#include +#include + +namespace brave_shields { + +TestFiltersProvider::TestFiltersProvider(const std::string& rules, + const std::string& resources) + : rules_(rules), resources_(resources) {} + +TestFiltersProvider::TestFiltersProvider(const base::FilePath& dat_location, + const std::string& resources) + : resources_(resources) { + CHECK(!dat_location.empty()); + + dat_buffer_ = brave_component_updater::ReadDATFileData(dat_location); + + CHECK(!dat_buffer_.empty()); +} + +TestFiltersProvider::~TestFiltersProvider() {} + +void TestFiltersProvider::LoadDATBuffer( + base::OnceCallback + cb) { + if (dat_buffer_.empty()) { + auto buffer = std::vector(rules_.begin(), rules_.end()); + std::move(cb).Run(false, buffer); + } else { + std::move(cb).Run(true, dat_buffer_); + } +} + +void TestFiltersProvider::LoadResources( + base::OnceCallback cb) { + std::move(cb).Run(resources_); +} + +} // namespace brave_shields diff --git a/components/brave_shields/browser/test_filters_provider.h b/components/brave_shields/browser/test_filters_provider.h new file mode 100644 index 000000000000..bf0c72d1d97e --- /dev/null +++ b/components/brave_shields/browser/test_filters_provider.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_TEST_FILTERS_PROVIDER_H_ +#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_TEST_FILTERS_PROVIDER_H_ + +#include +#include + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "brave/components/brave_component_updater/browser/dat_file_util.h" +#include "brave/components/brave_shields/browser/ad_block_filters_provider.h" +#include "brave/components/brave_shields/browser/ad_block_resource_provider.h" + +using brave_component_updater::DATFileDataBuffer; + +namespace brave_shields { + +class TestFiltersProvider : public AdBlockFiltersProvider, + public AdBlockResourceProvider { + public: + TestFiltersProvider(const std::string& rules, const std::string& resources); + TestFiltersProvider(const base::FilePath& dat_location, + const std::string& resources); + ~TestFiltersProvider() override; + + void LoadDATBuffer( + base::OnceCallback cb) override; + + void LoadResources( + base::OnceCallback cb) override; + + private: + DATFileDataBuffer dat_buffer_; + std::string rules_; + std::string resources_; +}; + +} // namespace brave_shields + +#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_TEST_FILTERS_PROVIDER_H_ diff --git a/components/cosmetic_filters/browser/cosmetic_filters_resources.cc b/components/cosmetic_filters/browser/cosmetic_filters_resources.cc index bfcdb57e154b..206fdced84a7 100644 --- a/components/cosmetic_filters/browser/cosmetic_filters_resources.cc +++ b/components/cosmetic_filters/browser/cosmetic_filters_resources.cc @@ -26,6 +26,7 @@ void CosmeticFiltersResources::HiddenClassIdSelectors( const std::string& input, const std::vector& exceptions, HiddenClassIdSelectorsCallback callback) { + DCHECK(ad_block_service_->GetTaskRunner()->RunsTasksInCurrentSequence()); absl::optional input_value = base::JSONReader::Read(input); if (!input_value || !input_value->is_dict()) { // Nothing to work with @@ -69,6 +70,7 @@ void CosmeticFiltersResources::HiddenClassIdSelectors( void CosmeticFiltersResources::UrlCosmeticResources( const std::string& url, UrlCosmeticResourcesCallback callback) { + DCHECK(ad_block_service_->GetTaskRunner()->RunsTasksInCurrentSequence()); auto resources = ad_block_service_->UrlCosmeticResources(url); std::move(callback).Run(resources ? std::move(resources.value()) : base::Value()); diff --git a/test/BUILD.gn b/test/BUILD.gn index 040019cd6a1d..29b951d6c8df 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -121,6 +121,7 @@ test("brave_unit_tests") { "//brave/components/brave_shields/browser/cosmetic_merge_unittest.cc", "//brave/components/brave_shields/browser/csp_merge_unittest.cc", "//brave/components/brave_shields/browser/https_everywhere_recently_used_cache_unittest.cpp", + "//brave/components/brave_shields/browser/test_filters_provider.cc", "//brave/components/brave_sync/crypto/crypto_unittest.cc", "//brave/components/content_settings/core/browser/brave_content_settings_pref_provider_unittest.cc", "//brave/components/content_settings/core/browser/brave_content_settings_utils_unittest.cc", @@ -717,6 +718,7 @@ if (!is_android) { "//brave/components/brave_rewards/browser/test/rewards_publisher_browsertest.cc", "//brave/components/brave_rewards/browser/test/rewards_state_browsertest.cc", "//brave/components/brave_shields/browser/https_everywhere_service_browsertest.cc", + "//brave/components/brave_shields/browser/test_filters_provider.cc", "//brave/components/content_settings/renderer/brave_content_settings_agent_impl_autoplay_browsertest.cc", "//brave/components/content_settings/renderer/brave_content_settings_agent_impl_browsertest.cc", "//brave/components/l10n/browser/locale_helper_mock.cc", diff --git a/test/base/testing_brave_browser_process.cc b/test/base/testing_brave_browser_process.cc index d95ab1ad1bf4..0dda32d06a4a 100644 --- a/test/base/testing_brave_browser_process.cc +++ b/test/base/testing_brave_browser_process.cc @@ -49,18 +49,6 @@ brave_shields::AdBlockService* TestingBraveBrowserProcess::ad_block_service() { return ad_block_service_.get(); } -brave_shields::AdBlockCustomFiltersService* -TestingBraveBrowserProcess::ad_block_custom_filters_service() { - NOTREACHED(); - return nullptr; -} - -brave_shields::AdBlockRegionalServiceManager* -TestingBraveBrowserProcess::ad_block_regional_service_manager() { - NOTREACHED(); - return nullptr; -} - #if BUILDFLAG(ENABLE_EXTENSIONS) brave_component_updater::ExtensionWhitelistService* TestingBraveBrowserProcess::extension_whitelist_service() { diff --git a/test/base/testing_brave_browser_process.h b/test/base/testing_brave_browser_process.h index 9a4d5caff1a1..5e034a09e627 100644 --- a/test/base/testing_brave_browser_process.h +++ b/test/base/testing_brave_browser_process.h @@ -42,10 +42,6 @@ class TestingBraveBrowserProcess : public BraveBrowserProcess { // BraveBrowserProcess overrides: void StartBraveServices() override; brave_shields::AdBlockService* ad_block_service() override; - brave_shields::AdBlockCustomFiltersService* ad_block_custom_filters_service() - override; - brave_shields::AdBlockRegionalServiceManager* - ad_block_regional_service_manager() override; #if BUILDFLAG(ENABLE_EXTENSIONS) brave_component_updater::ExtensionWhitelistService* extension_whitelist_service() override;