diff --git a/build/bromite_patches_list.txt b/build/bromite_patches_list.txt index a3f9d5b4..01d3d4d5 100644 --- a/build/bromite_patches_list.txt +++ b/build/bromite_patches_list.txt @@ -214,7 +214,7 @@ Add-kill-switch-for-unsupported-clangd-flags.patch 00Add-a-proxy-configuration-page--add-fixup-.patch 00OpenSearch--miscellaneous--fixup-.patch -00Eyeo-Adblock.patch +00AdblockPlus.patch 00Eyeo-Adblock-Remove-Privacy-Issues.patch 00Add-an-always-incognito-mode--win-fixup-.patch 00Experimental-user-scripts-support--win-fixup-.patch @@ -272,4 +272,5 @@ AudioBuffer-AnalyserNode-fp-mitigations.patch 00Remove-experimental-relative-c---abi-vtables.patch 00Disable-MathMLCore.patch 00fix-InitiatorOrigin--add-fixup-.patch -00109-Add-an-always-incognito-mode-fixup.patch \ No newline at end of file +00109-Add-an-always-incognito-mode-fixup.patch +00109-Fix-Adblock.patch \ No newline at end of file diff --git a/build/patches/00109-Fix-Adblock.patch b/build/patches/00109-Fix-Adblock.patch new file mode 100644 index 00000000..63e8f2e2 --- /dev/null +++ b/build/patches/00109-Fix-Adblock.patch @@ -0,0 +1,22 @@ +From: Your Name +Date: Fri, 3 Feb 2023 15:31:39 +0000 +Subject: 109 Fix Adblock + +--- + chrome/browser/ui/tab_helpers.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc +--- a/chrome/browser/ui/tab_helpers.cc ++++ b/chrome/browser/ui/tab_helpers.cc +@@ -335,6 +335,8 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) { + } + #endif + ++ adblock::AdblockControllerFactory::GetForBrowserContext( ++ web_contents->GetBrowserContext()); + AdblockWebContentObserver::CreateForWebContents( + web_contents, + adblock::SubscriptionServiceFactory::GetForBrowserContext( +-- +2.25.1 diff --git a/build/patches/00AdblockPlus.patch b/build/patches/00AdblockPlus.patch new file mode 100644 index 00000000..2965a0b2 --- /dev/null +++ b/build/patches/00AdblockPlus.patch @@ -0,0 +1,164375 @@ +From: Your Name +Date: Fri, 3 Feb 2023 13:17:30 +0000 +Subject: AdblockPlus + +--- + DEPS | 22 + + README.md | 12 + + base/trace_event/builtin_categories.h | 5 + + build/install-build-deps.sh | 12 +- + chrome/android/BUILD.gn | 8 + + .../android/chrome_common_shared_library.gni | 4 + + .../android/java/res/xml/main_preferences.xml | 18 +- + chrome/app/chrome_main_delegate.cc | 7 +- + chrome/browser/BUILD.gn | 29 + + chrome/browser/adblock/README.md | 3 + + .../adblock/adblock_content_browser_client.cc | 365 + + .../adblock/adblock_content_browser_client.h | 110 + + ...lock_content_browser_client_browsertest.cc | 122 + + ...adblock_content_browser_client_unittest.cc | 278 + + .../adblock/adblock_controller_factory.cc | 115 + + .../adblock/adblock_controller_factory.h | 50 + + .../adblock/adblock_debug_url_browsertest.cc | 116 + + .../adblock_filter_list_browsertest.cc | 215 + + ...ock_frame_hierarchy_builder_browsertest.cc | 123 + + .../adblock_multiple_tabs_browsertests.cc | 156 + + .../adblock/adblock_non_ascii_browsertest.cc | 77 + + ...dblock_subscription_service_browsertest.cc | 169 + + .../adblock_telemetry_service_browsertest.cc | 255 + + .../adblock_telemetry_service_factory.cc | 120 + + .../adblock_telemetry_service_factory.h | 56 + + ...ontent_security_policy_injector_factory.cc | 69 + + ...content_security_policy_injector_factory.h | 49 + + .../browser/adblock/element_hider_factory.cc | 63 + + .../browser/adblock/element_hider_factory.h | 47 + + .../resource_classification_runner_factory.cc | 71 + + .../resource_classification_runner_factory.h | 49 + + .../browser/adblock/session_stats_factory.cc | 64 + + .../browser/adblock/session_stats_factory.h | 47 + + .../adblock/sitekey_storage_factory.cc | 59 + + .../browser/adblock/sitekey_storage_factory.h | 47 + + ...ubscription_persistent_metadata_factory.cc | 63 + + ...subscription_persistent_metadata_factory.h | 49 + + .../adblock/subscription_service_factory.cc | 185 + + .../adblock/subscription_service_factory.h | 53 + + chrome/browser/android/adblock/adblock_jni.cc | 602 + + chrome/browser/android/adblock/adblock_jni.h | 74 + + .../android/adblock/adblock_jni_factory.cc | 75 + + .../android/adblock/adblock_jni_factory.h | 50 + + .../chrome_autocomplete_provider_client.cc | 5 + + .../client_hints/client_hints_browsertest.cc | 12 +- + chrome/browser/extensions/BUILD.gn | 7 + + chrome/browser/extensions/api/BUILD.gn | 5 + + .../adblock_private/adblock_private_api.cc | 740 + + .../api/adblock_private/adblock_private_api.h | 447 + + .../adblock_private_apitest.cc | 717 + + .../api/settings_private/prefs_util.cc | 19 + + ...browser_context_keyed_service_factories.cc | 6 + + chrome/browser/net/errorpage_browsertest.cc | 8 + + ..._page_load_metrics_observer_browsertest.cc | 7 +- + ...tifications_engagement_service_unittest.cc | 3 +- + chrome/browser/preferences/BUILD.gn | 5 + + .../prefs/chrome_command_line_pref_store.cc | 6 + + .../prefs/chrome_pref_service_factory.cc | 11 + + ...hrome_browser_main_extra_parts_profiles.cc | 20 + + .../profile_keyed_service_browsertest.cc | 28 +- + chrome/browser/resources/settings/BUILD.gn | 5 + + .../settings/adblock_page/adblock_page.html | 186 + + .../settings/adblock_page/adblock_page.ts | 317 + + .../settings/basic_page/basic_page.html | 7 + + .../settings/basic_page/basic_page.ts | 5 + + .../resources/settings/page_visibility.ts | 7 + + chrome/browser/resources/settings/route.ts | 9 + + chrome/browser/resources/settings/settings.ts | 5 + + .../settings/settings_menu/settings_menu.html | 7 + + .../resources/settings/settings_routes.ts | 5 + + .../safe_browsing_blocking_page_test.cc | 8 +- + ...subresource_filter_browser_test_harness.cc | 10 +- + chrome/browser/ui/BUILD.gn | 5 + + chrome/browser/ui/prefs/pref_watcher.cc | 13 + + chrome/browser/ui/tab_helpers.cc | 19 + + chrome/common/BUILD.gn | 3 + + .../common/extensions/api/_api_features.json | 14 + + .../extensions/api/_permission_features.json | 8 + + .../common/extensions/api/adblock_private.idl | 184 + + chrome/common/extensions/api/api_sources.gni | 5 + + .../permissions/chrome_api_permissions.cc | 6 + + .../permissions/permission_set_unittest.cc | 7 + + chrome/common/webui_url_constants.cc | 5 + + chrome/common/webui_url_constants.h | 5 + + chrome/test/BUILD.gn | 24 + + chrome/test/base/chrome_test_launcher.cc | 7 +- + chrome/test/base/in_process_browser_test.cc | 17 +- + chrome/test/data/adblock/innermost_frame.html | 20 + + chrome/test/data/adblock/middle_frame.html | 8 + + chrome/test/data/adblock/non-ascii.html | 9 + + chrome/test/data/adblock/outermost_frame.html | 20 + + chrome/test/data/adblock/resource.png | Bin 0 -> 47293 bytes + chrome/test/data/adblock/tab-restore.html | 26 + + .../api_test/adblock_private/empty.js | 0 + .../api_test/adblock_private/main.html | 29 + + .../api_test/adblock_private/manifest.json | 27 + + .../api_test/adblock_private/test.html | 8 + + .../api_test/adblock_private/test.js | 594 + + components/BUILD.gn | 13 + + components/adblock/CHANGELOG.md | 540 + + components/adblock/LICENSE | 674 + + components/adblock/README.md | 80 + + components/adblock/android/BUILD.gn | 146 + + .../adblock/android/adblock_strings.grd | 231 + + .../fragment_adblock_custom_item_add.png | Bin 0 -> 490 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 296 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 321 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 169 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 1522 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 696 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 747 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 194 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 1485 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 284 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 3393 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 600 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 638 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 240 bytes + .../fragment_adblock_custom_item_add.png | Bin 0 -> 933 bytes + .../fragment_adblock_custom_item_remove.png | Bin 0 -> 456 bytes + .../java/res/layout/adblock_custom_item.xml | 50 + + .../layout/adblock_custom_item_settings.xml | 65 + + .../layout/adblock_filter_lists_list_item.xml | 36 + + .../adblock_settings_locales_titles.xml | 98 + + .../java/res/xml/adblock_more_options.xml | 34 + + .../java/res/xml/adblock_preferences.xml | 56 + + ...blockComposeFilterSuggestionsCallback.java | 29 + + .../adblock/AdblockContentType.java | 62 + + .../components/adblock/AdblockController.java | 580 + + .../components/adblock/AdblockCounters.java | 86 + + .../components/adblock/AdblockElement.java | 85 + + .../AdblockAllowedDomainsFragment.java | 77 + + .../AdblockCustomFilterListsFragment.java | 107 + + .../AdblockCustomFiltersFragment.java | 76 + + .../settings/AdblockCustomItemFragment.java | 166 + + .../settings/AdblockFilterListsAdapter.java | 115 + + .../settings/AdblockFilterListsFragment.java | 54 + + .../settings/AdblockMoreOptionsFragment.java | 34 + + .../settings/AdblockSettingsFragment.java | 137 + + .../adblock/AdblockControllerTest.java | 132 + + .../adblock/AdblockFilterFragmentTest.java | 73 + + .../adblock/AdblockPopupInfoBarTest.java | 127 + + .../adblock/AdblockPopupMessageTest.java | 112 + + .../adblock/TestPagesCircumventionTest.java | 89 + + .../components/adblock/TestPagesCspTest.java | 123 + + .../adblock/TestPagesElemhideEmuInvTest.java | 140 + + .../adblock/TestPagesElemhideEmuTest.java | 190 + + .../adblock/TestPagesElemhideTest.java | 214 + + .../adblock/TestPagesExceptionTest.java | 216 + + .../adblock/TestPagesFilterTest.java | 280 + + .../adblock/TestPagesHeaderFilterTest.java | 126 + + .../adblock/TestPagesRewriteTest.java | 157 + + .../adblock/TestPagesSiteKeyTest.java | 79 + + .../adblock/TestPagesSnippetsTest.java | 467 + + .../adblock/TestPagesTestsHelper.java | 406 + + .../adblock/TestPagesWebsocketTest.java | 79 + + .../translations/adblock_strings_af.xtb | 4 + + .../translations/adblock_strings_am.xtb | 14 + + .../translations/adblock_strings_ar.xtb | 15 + + .../translations/adblock_strings_as.xtb | 4 + + .../translations/adblock_strings_az.xtb | 4 + + .../translations/adblock_strings_be.xtb | 4 + + .../translations/adblock_strings_bg.xtb | 17 + + .../translations/adblock_strings_bn.xtb | 14 + + .../translations/adblock_strings_bs.xtb | 14 + + .../translations/adblock_strings_ca.xtb | 14 + + .../translations/adblock_strings_cs.xtb | 14 + + .../translations/adblock_strings_da.xtb | 14 + + .../translations/adblock_strings_de.xtb | 15 + + .../translations/adblock_strings_el.xtb | 15 + + .../translations/adblock_strings_en-GB.xtb | 14 + + .../translations/adblock_strings_es-419.xtb | 15 + + .../translations/adblock_strings_es.xtb | 15 + + .../translations/adblock_strings_et.xtb | 14 + + .../translations/adblock_strings_eu.xtb | 4 + + .../translations/adblock_strings_fa.xtb | 14 + + .../translations/adblock_strings_fi.xtb | 14 + + .../translations/adblock_strings_fil.xtb | 14 + + .../translations/adblock_strings_fr-CA.xtb | 14 + + .../translations/adblock_strings_fr.xtb | 14 + + .../translations/adblock_strings_gl.xtb | 4 + + .../translations/adblock_strings_gu.xtb | 4 + + .../translations/adblock_strings_hi.xtb | 14 + + .../translations/adblock_strings_hr.xtb | 14 + + .../translations/adblock_strings_hu.xtb | 15 + + .../translations/adblock_strings_hy.xtb | 4 + + .../translations/adblock_strings_id.xtb | 14 + + .../translations/adblock_strings_is.xtb | 4 + + .../translations/adblock_strings_it.xtb | 15 + + .../translations/adblock_strings_iw.xtb | 14 + + .../translations/adblock_strings_ja.xtb | 15 + + .../translations/adblock_strings_ka.xtb | 4 + + .../translations/adblock_strings_kk.xtb | 14 + + .../translations/adblock_strings_km.xtb | 14 + + .../translations/adblock_strings_kn.xtb | 4 + + .../translations/adblock_strings_ko.xtb | 15 + + .../translations/adblock_strings_ky.xtb | 4 + + .../translations/adblock_strings_lo.xtb | 4 + + .../translations/adblock_strings_lt.xtb | 14 + + .../translations/adblock_strings_lv.xtb | 14 + + .../translations/adblock_strings_mk.xtb | 14 + + .../translations/adblock_strings_ml.xtb | 4 + + .../translations/adblock_strings_mn.xtb | 4 + + .../translations/adblock_strings_mr.xtb | 4 + + .../translations/adblock_strings_ms.xtb | 14 + + .../translations/adblock_strings_my.xtb | 14 + + .../translations/adblock_strings_ne.xtb | 4 + + .../translations/adblock_strings_nl.xtb | 15 + + .../translations/adblock_strings_no.xtb | 4 + + .../translations/adblock_strings_or.xtb | 4 + + .../translations/adblock_strings_pa.xtb | 4 + + .../translations/adblock_strings_pl.xtb | 15 + + .../translations/adblock_strings_pt-BR.xtb | 15 + + .../translations/adblock_strings_pt-PT.xtb | 15 + + .../translations/adblock_strings_ro.xtb | 14 + + .../translations/adblock_strings_ru.xtb | 15 + + .../translations/adblock_strings_si.xtb | 4 + + .../translations/adblock_strings_sk.xtb | 14 + + .../translations/adblock_strings_sl.xtb | 14 + + .../translations/adblock_strings_sq.xtb | 4 + + .../translations/adblock_strings_sr-Latn.xtb | 4 + + .../translations/adblock_strings_sr.xtb | 14 + + .../translations/adblock_strings_sv.xtb | 14 + + .../translations/adblock_strings_sw.xtb | 14 + + .../translations/adblock_strings_ta.xtb | 4 + + .../translations/adblock_strings_te.xtb | 4 + + .../translations/adblock_strings_th.xtb | 14 + + .../translations/adblock_strings_tr.xtb | 15 + + .../translations/adblock_strings_uk.xtb | 14 + + .../translations/adblock_strings_ur.xtb | 14 + + .../translations/adblock_strings_uz.xtb | 4 + + .../translations/adblock_strings_vi.xtb | 14 + + .../translations/adblock_strings_zh-CN.xtb | 15 + + .../translations/adblock_strings_zh-HK.xtb | 4 + + .../translations/adblock_strings_zh-TW.xtb | 14 + + .../translations/adblock_strings_zu.xtb | 4 + + components/adblock/content/BUILD.gn | 22 + + components/adblock/content/browser/BUILD.gn | 123 + + .../content/browser/adblock_content_utils.cc | 116 + + .../content/browser/adblock_content_utils.h | 33 + + .../content/browser/adblock_filter_match.h | 30 + + .../browser/adblock_url_loader_factory.cc | 709 + + .../browser/adblock_url_loader_factory.h | 93 + + .../adblock_url_loader_factory_for_test.cc | 196 + + .../adblock_url_loader_factory_for_test.h | 74 + + .../browser/adblock_webcontents_observer.cc | 120 + + .../browser/adblock_webcontents_observer.h | 74 + + .../content_security_policy_injector.h | 61 + + .../content_security_policy_injector_impl.cc | 125 + + .../content_security_policy_injector_impl.h | 65 + + .../adblock/content/browser/element_hider.h | 70 + + .../content/browser/element_hider_impl.cc | 330 + + .../content/browser/element_hider_impl.h | 61 + + .../browser/frame_hierarchy_builder.cc | 89 + + .../content/browser/frame_hierarchy_builder.h | 63 + + .../browser/resource_classification_runner.h | 101 + + .../resource_classification_runner_impl.cc | 412 + + .../resource_classification_runner_impl.h | 152 + + .../content/browser/session_stats_impl.cc | 86 + + .../content/browser/session_stats_impl.h | 69 + + .../test/adblock_content_utils_test.cc | 113 + + .../test/adblock_url_loader_factory_test.cc | 289 + + .../test/adblock_webcontents_observer_test.cc | 136 + + ...tent_security_policy_injector_impl_test.cc | 243 + + .../browser/test/element_hider_impl_test.cc | 264 + + .../test/frame_hierarchy_builder_test.cc | 153 + + ...dblock_content_security_policy_injector.cc | 28 + + ...adblock_content_security_policy_injector.h | 44 + + .../browser/test/mock_element_hider.cc | 26 + + .../content/browser/test/mock_element_hider.h | 55 + + .../test/mock_frame_hierarchy_builder.cc | 26 + + .../test/mock_frame_hierarchy_builder.h | 49 + + .../mock_resource_classification_runner.cc | 36 + + .../mock_resource_classification_runner.h | 83 + + ...esource_classification_runner_impl_test.cc | 385 + + .../browser/test/session_stats_impl_test.cc | 159 + + components/adblock/core/BUILD.gn | 188 + + .../activeping_telemetry_topic_provider.cc | 241 + + .../activeping_telemetry_topic_provider.h | 83 + + components/adblock/core/adblock_controller.h | 94 + + .../adblock/core/adblock_controller_impl.cc | 338 + + .../adblock/core/adblock_controller_impl.h | 112 + + .../core/adblock_controller_legacy_impl.cc | 272 + + .../core/adblock_controller_legacy_impl.h | 93 + + components/adblock/core/adblock_switches.cc | 26 + + components/adblock/core/adblock_switches.h | 30 + + .../adblock/core/adblock_telemetry_service.cc | 237 + + .../adblock/core/adblock_telemetry_service.h | 107 + + components/adblock/core/classifier/BUILD.gn | 77 + + .../core/classifier/resource_classifier.cc | 24 + + .../core/classifier/resource_classifier.h | 82 + + .../classifier/resource_classifier_impl.cc | 221 + + .../classifier/resource_classifier_impl.h | 67 + + .../test/mock_resource_classifier.cc | 26 + + .../test/mock_resource_classifier.h | 58 + + .../test/resource_classifier_impl_test.cc | 439 + + .../test/resource_classifier_perftest.cc | 219 + + components/adblock/core/common/BUILD.gn | 85 + + .../adblock/core/common/adblock_constants.cc | 152 + + .../adblock/core/common/adblock_constants.h | 40 + + .../adblock/core/common/adblock_prefs.cc | 122 + + .../adblock/core/common/adblock_prefs.h | 46 + + .../adblock/core/common/adblock_utils.cc | 168 + + .../adblock/core/common/adblock_utils.h | 81 + + .../adblock/core/common/content_type.cc | 55 + + components/adblock/core/common/content_type.h | 46 + + .../adblock/core/common/converter_result.cc | 27 + + .../adblock/core/common/converter_result.h | 42 + + .../adblock/core/common/flatbuffer_data.cc | 90 + + .../adblock/core/common/flatbuffer_data.h | 85 + + .../adblock/core/common/header_filter_data.h | 38 + + .../core/common/keyword_extractor_utils.cc | 29 + + .../core/common/keyword_extractor_utils.h | 31 + + components/adblock/core/common/sitekey.h | 29 + + .../core/common/test/adblock_utils_test.cc | 43 + + .../core/common/test/flatbuffer_data_test.cc | 78 + + .../adblock/core/configuration/BUILD.gn | 54 + + .../fake_filtering_configuration.cc | 107 + + .../fake_filtering_configuration.h | 65 + + .../configuration/filtering_configuration.h | 90 + + .../persistent_filtering_configuration.cc | 231 + + .../persistent_filtering_configuration.h | 80 + + ...persistent_filtering_configuration_test.cc | 239 + + components/adblock/core/converter/BUILD.gn | 96 + + .../adblock/core/converter/converter.cc | 1029 + + components/adblock/core/converter/converter.h | 108 + + .../core/converter/converter_standalone.cc | 87 + + .../converter/filter_keyword_extractor.cc | 62 + + .../core/converter/filter_keyword_extractor.h | 62 + + components/adblock/core/converter/metadata.cc | 157 + + components/adblock/core/converter/metadata.h | 67 + + .../core/converter/snippet_tokenizer.h | 36 + + .../core/converter/snippet_tokenizer_impl.cc | 100 + + .../core/converter/snippet_tokenizer_impl.h | 49 + + .../core/converter/test/converter_perftest.cc | 60 + + .../core/converter/test/converter_test.cc | 2148 + + .../test/filter_keyword_extractor_test.cc | 69 + + .../core/converter/test/metadata_test.cc | 195 + + .../converter/test/mock_snippet_tokenizer.cc | 26 + + .../converter/test/mock_snippet_tokenizer.h | 43 + + .../test/snippet_tokenizer_impl_test.cc | 134 + + components/adblock/core/features.cc | 25 + + components/adblock/core/features.h | 31 + + .../core/schema/filter_list_schema.fbs | 166 + + components/adblock/core/session_stats.h | 44 + + components/adblock/core/sitekey_storage.h | 53 + + .../adblock/core/sitekey_storage_impl.cc | 144 + + .../adblock/core/sitekey_storage_impl.h | 59 + + components/adblock/core/subscription/BUILD.gn | 122 + + .../core/subscription/domain_splitter.cc | 45 + + .../core/subscription/domain_splitter.h | 45 + + .../subscription/installed_subscription.cc | 42 + + .../subscription/installed_subscription.h | 139 + + .../installed_subscription_impl.cc | 643 + + .../installed_subscription_impl.h | 174 + + .../ongoing_subscription_request.h | 50 + + .../ongoing_subscription_request_impl.cc | 213 + + .../ongoing_subscription_request_impl.h | 77 + + .../preloaded_subscription_provider.h | 56 + + .../preloaded_subscription_provider_impl.cc | 141 + + .../preloaded_subscription_provider_impl.h | 59 + + .../adblock/core/subscription/subscription.cc | 24 + + .../adblock/core/subscription/subscription.h | 76 + + .../subscription/subscription_collection.h | 93 + + .../subscription_collection_impl.cc | 384 + + .../subscription_collection_impl.h | 91 + + .../core/subscription/subscription_config.cc | 320 + + .../core/subscription/subscription_config.h | 121 + + .../subscription/subscription_downloader.h | 66 + + .../subscription_downloader_impl.cc | 289 + + .../subscription_downloader_impl.h | 106 + + .../subscription_persistent_metadata.h | 86 + + .../subscription_persistent_metadata_impl.cc | 166 + + .../subscription_persistent_metadata_impl.h | 61 + + .../subscription_persistent_storage.h | 60 + + .../subscription_persistent_storage_impl.cc | 225 + + .../subscription_persistent_storage_impl.h | 77 + + .../core/subscription/subscription_service.h | 89 + + .../subscription/subscription_service_impl.cc | 543 + + .../subscription/subscription_service_impl.h | 132 + + .../core/subscription/subscription_updater.h | 35 + + .../subscription/subscription_updater_impl.cc | 65 + + .../subscription/subscription_updater_impl.h | 52 + + .../subscription/subscription_validator.cc | 24 + + .../subscription/subscription_validator.h | 54 + + .../subscription_validator_impl.cc | 123 + + .../subscription_validator_impl.h | 56 + + .../test/installed_subscription_impl_test.cc | 74 + + .../test/mock_installed_subscription.cc | 26 + + .../test/mock_installed_subscription.h | 101 + + .../subscription/test/mock_subscription.cc | 36 + + .../subscription/test/mock_subscription.h | 51 + + .../test/mock_subscription_collection.cc | 26 + + .../test/mock_subscription_collection.h | 96 + + .../test/mock_subscription_downloader.cc | 25 + + .../test/mock_subscription_downloader.h | 48 + + .../mock_subscription_persistent_metadata.cc | 27 + + .../mock_subscription_persistent_metadata.h | 76 + + .../test/mock_subscription_service.cc | 36 + + .../test/mock_subscription_service.h | 54 + + .../test/mock_subscription_updater.cc | 25 + + .../test/mock_subscription_updater.h | 38 + + .../ongoing_subscription_request_impl_test.cc | 354 + + ...eloaded_subscription_provider_impl_test.cc | 231 + + .../test/subscription_collection_impl_test.cc | 839 + + .../test/subscription_downloader_impl_test.cc | 592 + + ...scription_persistent_metadata_impl_test.cc | 213 + + ...bscription_persistent_storage_impl_test.cc | 311 + + .../test/subscription_service_impl_test.cc | 951 + + .../test/subscription_updater_impl_test.cc | 98 + + .../test/subscription_validator_impl_test.cc | 180 + + .../test/url_keyword_extractor_test.cc | 74 + + .../subscription/url_keyword_extractor.cc | 59 + + .../core/subscription/url_keyword_extractor.h | 61 + + ...ctiveping_telemetry_topic_provider_test.cc | 318 + + .../core/test/adblock_controller_impl_test.cc | 466 + + .../adblock_controller_legacy_impl_test.cc | 312 + + .../adblock_telemetry_service_unittest.cc | 356 + + .../core/test/bundled_subscription_test.cc | 49 + + .../core/test/mock_adblock_controller.cc | 33 + + .../core/test/mock_adblock_controller.h | 87 + + .../adblock/core/test/mock_sitekey_storage.cc | 26 + + .../adblock/core/test/mock_sitekey_storage.h | 49 + + .../core/test/sitekey_storage_impl_test.cc | 131 + + .../adblock/docs/ad-filtering/README.md | 9 + + .../ad-filtering/element-hiding-sequence.png | Bin 0 -> 177168 bytes + .../ad-filtering/element-hiding-sequence.txt | 32 + + .../docs/ad-filtering/element-hiding.md | 11 + + .../adblock/docs/ad-filtering/filter-lists.md | 42 + + .../request-filter-matching-sequence.png | Bin 0 -> 140660 bytes + .../request_filter_matching_sequence.txt | 28 + + .../docs/ad-filtering/resource-filtering.md | 28 + + .../response-filter-matching-sequence.png | Bin 0 -> 160751 bytes + .../response_filter_matching_sequence.txt | 30 + + .../adblock/docs/ad-filtering/snippets.md | 7 + + components/adblock/docs/adr/README.md | 3 + + .../docs/adr/consuming-full-filter-lists.md | 8 + + ...ving-user-counting-to-dedicated-service.md | 5 + + .../adr/not-extending-subresource-filter.md | 13 + + ...ring-filter-lists-in-flatbuffers-format.md | 17 + + .../adblock/docs/data-collection/README.md | 11 + + .../docs/data-collection/user-counting.md | 38 + + components/adblock/docs/design-overview.md | 32 + + components/adblock/docs/developer-notes.md | 117 + + .../adblock/docs/initialization-sequence.png | Bin 0 -> 129976 bytes + .../adblock/docs/initialization-sequence.txt | 27 + + components/adblock/docs/integration-how-to.md | 220 + + components/adblock/docs/settings/README.md | 21 + + .../docs/settings/user-setting-sequence.png | Bin 0 -> 61104 bytes + .../docs/settings/user-setting-sequence.txt | 14 + + components/adblock/features.gni | 44 + + components/adblock_comparison/BUILD.gn | 47 + + .../libadblockplus_reference_database.cc | 239 + + .../libadblockplus_reference_database.h | 98 + + .../adblock_comparison/test_request_reader.cc | 109 + + .../adblock_comparison/test_request_reader.h | 54 + + .../verify_flatbuffer_adblocking.cc | 263 + + components/resources/BUILD.gn | 9 + + components/resources/adblock_resources.grdp | 23 + + components/resources/adblocking/.gitignore | 1 + + components/resources/adblocking/BUILD.gn | 70 + + components/resources/adblocking/anticv.txt | 2510 + + components/resources/adblocking/easylist.txt | 15550 +++++ + components/resources/adblocking/elemhide.js | 43 + + .../adblocking/elemhide_for_selector.jst | 53 + + .../resources/adblocking/elemhideemu.jst | 1436 + + .../resources/adblocking/exceptionrules.txt | 5998 ++ + components/resources/adblocking/update.sh | 30 + + components/resources/components_resources.grd | 1 + + components/test/data/adblock/anticv.txt | 1317 + + components/test/data/adblock/easylist.txt | 56515 ++++++++++++++++ + .../test/data/adblock/exceptionrules.txt | 17738 +++++ + components/test/data/adblock/longurl.txt | 1 + + .../data/adblock/random_shuf_100.tsv.sqlite | Bin 0 -> 40960 bytes + components/variations/service/BUILD.gn | 4 + + .../loader/navigation_url_loader_impl.cc | 6 +- + .../renderer_host/render_frame_host_impl.cc | 11 +- + .../renderer_host/render_frame_host_impl.h | 8 + + content/public/browser/render_frame_host.h | 7 + + content/public/common/isolated_world_ids.h | 8 + + content/public/test/fake_local_frame.cc | 7 + + content/public/test/fake_local_frame.h | 5 + + content/renderer/render_frame_impl.h | 4 + + ...web_request_proxying_url_loader_factory.cc | 5 + + .../browser/extension_event_histogram_value.h | 13 + + .../extension_function_histogram_value.h | 31 + + .../common/mojom/api_permission_id.mojom | 5 + + gclient/.gclient | 25 + + gclient/.gclient_ci_android | 22 + + gclient/.gclient_ci_linux | 21 + + gclient/.gclient_ci_windows | 22 + + net/url_request/redirect_info.cc | 4 + + net/url_request/redirect_info.h | 8 + + .../network/public/cpp/net_ipc_param_traits.h | 5 + + .../blink/public/mojom/frame/frame.mojom | 8 + + third_party/blink/public/web/web_document.h | 12 + + .../renderer/core/exported/web_document.cc | 52 + + .../core/frame/local_frame_mojo_handler.cc | 13 + + .../core/frame/local_frame_mojo_handler.h | 5 + + .../url_loader/mojo_url_loader_client.cc | 6 +- + tools/adblock/interdiff.py | 87 + + tools/metrics/histograms/enums.xml | 36 + + tools/perf/benchmarks/eyeo.py | 1193 + + tools/perf/page_sets/eyeo_page_set.py | 978 + + 504 files changed, 148147 insertions(+), 22 deletions(-) + create mode 100644 chrome/browser/adblock/README.md + create mode 100644 chrome/browser/adblock/adblock_content_browser_client.cc + create mode 100644 chrome/browser/adblock/adblock_content_browser_client.h + create mode 100644 chrome/browser/adblock/adblock_content_browser_client_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_content_browser_client_unittest.cc + create mode 100644 chrome/browser/adblock/adblock_controller_factory.cc + create mode 100644 chrome/browser/adblock/adblock_controller_factory.h + create mode 100644 chrome/browser/adblock/adblock_debug_url_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_filter_list_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_frame_hierarchy_builder_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_multiple_tabs_browsertests.cc + create mode 100644 chrome/browser/adblock/adblock_non_ascii_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_subscription_service_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_telemetry_service_browsertest.cc + create mode 100644 chrome/browser/adblock/adblock_telemetry_service_factory.cc + create mode 100644 chrome/browser/adblock/adblock_telemetry_service_factory.h + create mode 100644 chrome/browser/adblock/content_security_policy_injector_factory.cc + create mode 100644 chrome/browser/adblock/content_security_policy_injector_factory.h + create mode 100644 chrome/browser/adblock/element_hider_factory.cc + create mode 100644 chrome/browser/adblock/element_hider_factory.h + create mode 100644 chrome/browser/adblock/resource_classification_runner_factory.cc + create mode 100644 chrome/browser/adblock/resource_classification_runner_factory.h + create mode 100644 chrome/browser/adblock/session_stats_factory.cc + create mode 100644 chrome/browser/adblock/session_stats_factory.h + create mode 100644 chrome/browser/adblock/sitekey_storage_factory.cc + create mode 100644 chrome/browser/adblock/sitekey_storage_factory.h + create mode 100644 chrome/browser/adblock/subscription_persistent_metadata_factory.cc + create mode 100644 chrome/browser/adblock/subscription_persistent_metadata_factory.h + create mode 100644 chrome/browser/adblock/subscription_service_factory.cc + create mode 100644 chrome/browser/adblock/subscription_service_factory.h + create mode 100644 chrome/browser/android/adblock/adblock_jni.cc + create mode 100644 chrome/browser/android/adblock/adblock_jni.h + create mode 100644 chrome/browser/android/adblock/adblock_jni_factory.cc + create mode 100644 chrome/browser/android/adblock/adblock_jni_factory.h + create mode 100644 chrome/browser/extensions/api/adblock_private/adblock_private_api.cc + create mode 100644 chrome/browser/extensions/api/adblock_private/adblock_private_api.h + create mode 100644 chrome/browser/extensions/api/adblock_private/adblock_private_apitest.cc + create mode 100644 chrome/browser/resources/settings/adblock_page/adblock_page.html + create mode 100644 chrome/browser/resources/settings/adblock_page/adblock_page.ts + create mode 100644 chrome/common/extensions/api/adblock_private.idl + create mode 100644 chrome/test/data/adblock/innermost_frame.html + create mode 100644 chrome/test/data/adblock/middle_frame.html + create mode 100644 chrome/test/data/adblock/non-ascii.html + create mode 100644 chrome/test/data/adblock/outermost_frame.html + create mode 100644 chrome/test/data/adblock/resource.png + create mode 100644 chrome/test/data/adblock/tab-restore.html + create mode 100644 chrome/test/data/extensions/api_test/adblock_private/empty.js + create mode 100644 chrome/test/data/extensions/api_test/adblock_private/main.html + create mode 100644 chrome/test/data/extensions/api_test/adblock_private/manifest.json + create mode 100644 chrome/test/data/extensions/api_test/adblock_private/test.html + create mode 100644 chrome/test/data/extensions/api_test/adblock_private/test.js + create mode 100644 components/adblock/CHANGELOG.md + create mode 100644 components/adblock/LICENSE + create mode 100644 components/adblock/README.md + create mode 100644 components/adblock/android/BUILD.gn + create mode 100644 components/adblock/android/adblock_strings.grd + create mode 100644 components/adblock/android/java/res/drawable-hdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-hdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-mdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-mdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-night-hdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-night-hdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-night-mdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-night-mdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-night-xhdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-night-xhdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-night-xxhdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-night-xxhdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-xhdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-xhdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/drawable-xxhdpi/fragment_adblock_custom_item_add.png + create mode 100644 components/adblock/android/java/res/drawable-xxhdpi/fragment_adblock_custom_item_remove.png + create mode 100644 components/adblock/android/java/res/layout/adblock_custom_item.xml + create mode 100644 components/adblock/android/java/res/layout/adblock_custom_item_settings.xml + create mode 100644 components/adblock/android/java/res/layout/adblock_filter_lists_list_item.xml + create mode 100644 components/adblock/android/java/res/values/adblock_settings_locales_titles.xml + create mode 100644 components/adblock/android/java/res/xml/adblock_more_options.xml + create mode 100644 components/adblock/android/java/res/xml/adblock_preferences.xml + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockComposeFilterSuggestionsCallback.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockContentType.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockController.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockCounters.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockElement.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockAllowedDomainsFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockCustomFilterListsFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockCustomFiltersFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockCustomItemFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockFilterListsAdapter.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockFilterListsFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockMoreOptionsFragment.java + create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/settings/AdblockSettingsFragment.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/AdblockControllerTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/AdblockFilterFragmentTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/AdblockPopupInfoBarTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/AdblockPopupMessageTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesCircumventionTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesCspTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesElemhideEmuInvTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesElemhideEmuTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesElemhideTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesExceptionTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesFilterTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesHeaderFilterTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesRewriteTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesSiteKeyTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesSnippetsTest.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesTestsHelper.java + create mode 100644 components/adblock/android/javatests/src/org/chromium/components/adblock/TestPagesWebsocketTest.java + create mode 100644 components/adblock/android/translations/adblock_strings_af.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_am.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ar.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_as.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_az.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_be.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_bg.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_bn.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_bs.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ca.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_cs.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_da.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_de.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_el.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_en-GB.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_es-419.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_es.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_et.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_eu.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_fa.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_fi.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_fil.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_fr-CA.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_fr.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_gl.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_gu.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_hi.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_hr.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_hu.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_hy.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_id.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_is.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_it.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_iw.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ja.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ka.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_kk.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_km.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_kn.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ko.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ky.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_lo.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_lt.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_lv.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_mk.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ml.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_mn.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_mr.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ms.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_my.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ne.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_nl.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_no.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_or.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_pa.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_pl.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_pt-BR.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_pt-PT.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ro.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ru.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_si.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sk.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sl.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sq.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sr-Latn.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sr.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sv.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_sw.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ta.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_te.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_th.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_tr.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_uk.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_ur.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_uz.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_vi.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_zh-CN.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_zh-HK.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_zh-TW.xtb + create mode 100644 components/adblock/android/translations/adblock_strings_zu.xtb + create mode 100644 components/adblock/content/BUILD.gn + create mode 100644 components/adblock/content/browser/BUILD.gn + create mode 100644 components/adblock/content/browser/adblock_content_utils.cc + create mode 100644 components/adblock/content/browser/adblock_content_utils.h + create mode 100644 components/adblock/content/browser/adblock_filter_match.h + create mode 100644 components/adblock/content/browser/adblock_url_loader_factory.cc + create mode 100644 components/adblock/content/browser/adblock_url_loader_factory.h + create mode 100644 components/adblock/content/browser/adblock_url_loader_factory_for_test.cc + create mode 100644 components/adblock/content/browser/adblock_url_loader_factory_for_test.h + create mode 100644 components/adblock/content/browser/adblock_webcontents_observer.cc + create mode 100644 components/adblock/content/browser/adblock_webcontents_observer.h + create mode 100644 components/adblock/content/browser/content_security_policy_injector.h + create mode 100644 components/adblock/content/browser/content_security_policy_injector_impl.cc + create mode 100644 components/adblock/content/browser/content_security_policy_injector_impl.h + create mode 100644 components/adblock/content/browser/element_hider.h + create mode 100644 components/adblock/content/browser/element_hider_impl.cc + create mode 100644 components/adblock/content/browser/element_hider_impl.h + create mode 100644 components/adblock/content/browser/frame_hierarchy_builder.cc + create mode 100644 components/adblock/content/browser/frame_hierarchy_builder.h + create mode 100644 components/adblock/content/browser/resource_classification_runner.h + create mode 100644 components/adblock/content/browser/resource_classification_runner_impl.cc + create mode 100644 components/adblock/content/browser/resource_classification_runner_impl.h + create mode 100644 components/adblock/content/browser/session_stats_impl.cc + create mode 100644 components/adblock/content/browser/session_stats_impl.h + create mode 100644 components/adblock/content/browser/test/adblock_content_utils_test.cc + create mode 100644 components/adblock/content/browser/test/adblock_url_loader_factory_test.cc + create mode 100644 components/adblock/content/browser/test/adblock_webcontents_observer_test.cc + create mode 100644 components/adblock/content/browser/test/content_security_policy_injector_impl_test.cc + create mode 100644 components/adblock/content/browser/test/element_hider_impl_test.cc + create mode 100644 components/adblock/content/browser/test/frame_hierarchy_builder_test.cc + create mode 100644 components/adblock/content/browser/test/mock_adblock_content_security_policy_injector.cc + create mode 100644 components/adblock/content/browser/test/mock_adblock_content_security_policy_injector.h + create mode 100644 components/adblock/content/browser/test/mock_element_hider.cc + create mode 100644 components/adblock/content/browser/test/mock_element_hider.h + create mode 100644 components/adblock/content/browser/test/mock_frame_hierarchy_builder.cc + create mode 100644 components/adblock/content/browser/test/mock_frame_hierarchy_builder.h + create mode 100644 components/adblock/content/browser/test/mock_resource_classification_runner.cc + create mode 100644 components/adblock/content/browser/test/mock_resource_classification_runner.h + create mode 100644 components/adblock/content/browser/test/resource_classification_runner_impl_test.cc + create mode 100644 components/adblock/content/browser/test/session_stats_impl_test.cc + create mode 100644 components/adblock/core/BUILD.gn + create mode 100644 components/adblock/core/activeping_telemetry_topic_provider.cc + create mode 100644 components/adblock/core/activeping_telemetry_topic_provider.h + create mode 100644 components/adblock/core/adblock_controller.h + create mode 100644 components/adblock/core/adblock_controller_impl.cc + create mode 100644 components/adblock/core/adblock_controller_impl.h + create mode 100644 components/adblock/core/adblock_controller_legacy_impl.cc + create mode 100644 components/adblock/core/adblock_controller_legacy_impl.h + create mode 100644 components/adblock/core/adblock_switches.cc + create mode 100644 components/adblock/core/adblock_switches.h + create mode 100644 components/adblock/core/adblock_telemetry_service.cc + create mode 100644 components/adblock/core/adblock_telemetry_service.h + create mode 100644 components/adblock/core/classifier/BUILD.gn + create mode 100644 components/adblock/core/classifier/resource_classifier.cc + create mode 100644 components/adblock/core/classifier/resource_classifier.h + create mode 100644 components/adblock/core/classifier/resource_classifier_impl.cc + create mode 100644 components/adblock/core/classifier/resource_classifier_impl.h + create mode 100644 components/adblock/core/classifier/test/mock_resource_classifier.cc + create mode 100644 components/adblock/core/classifier/test/mock_resource_classifier.h + create mode 100644 components/adblock/core/classifier/test/resource_classifier_impl_test.cc + create mode 100644 components/adblock/core/classifier/test/resource_classifier_perftest.cc + create mode 100644 components/adblock/core/common/BUILD.gn + create mode 100644 components/adblock/core/common/adblock_constants.cc + create mode 100644 components/adblock/core/common/adblock_constants.h + create mode 100644 components/adblock/core/common/adblock_prefs.cc + create mode 100644 components/adblock/core/common/adblock_prefs.h + create mode 100644 components/adblock/core/common/adblock_utils.cc + create mode 100644 components/adblock/core/common/adblock_utils.h + create mode 100644 components/adblock/core/common/content_type.cc + create mode 100644 components/adblock/core/common/content_type.h + create mode 100644 components/adblock/core/common/converter_result.cc + create mode 100644 components/adblock/core/common/converter_result.h + create mode 100644 components/adblock/core/common/flatbuffer_data.cc + create mode 100644 components/adblock/core/common/flatbuffer_data.h + create mode 100644 components/adblock/core/common/header_filter_data.h + create mode 100644 components/adblock/core/common/keyword_extractor_utils.cc + create mode 100644 components/adblock/core/common/keyword_extractor_utils.h + create mode 100644 components/adblock/core/common/sitekey.h + create mode 100644 components/adblock/core/common/test/adblock_utils_test.cc + create mode 100644 components/adblock/core/common/test/flatbuffer_data_test.cc + create mode 100644 components/adblock/core/configuration/BUILD.gn + create mode 100644 components/adblock/core/configuration/fake_filtering_configuration.cc + create mode 100644 components/adblock/core/configuration/fake_filtering_configuration.h + create mode 100644 components/adblock/core/configuration/filtering_configuration.h + create mode 100644 components/adblock/core/configuration/persistent_filtering_configuration.cc + create mode 100644 components/adblock/core/configuration/persistent_filtering_configuration.h + create mode 100644 components/adblock/core/configuration/persistent_filtering_configuration_test.cc + create mode 100644 components/adblock/core/converter/BUILD.gn + create mode 100644 components/adblock/core/converter/converter.cc + create mode 100644 components/adblock/core/converter/converter.h + create mode 100644 components/adblock/core/converter/converter_standalone.cc + create mode 100644 components/adblock/core/converter/filter_keyword_extractor.cc + create mode 100644 components/adblock/core/converter/filter_keyword_extractor.h + create mode 100644 components/adblock/core/converter/metadata.cc + create mode 100644 components/adblock/core/converter/metadata.h + create mode 100644 components/adblock/core/converter/snippet_tokenizer.h + create mode 100644 components/adblock/core/converter/snippet_tokenizer_impl.cc + create mode 100644 components/adblock/core/converter/snippet_tokenizer_impl.h + create mode 100644 components/adblock/core/converter/test/converter_perftest.cc + create mode 100644 components/adblock/core/converter/test/converter_test.cc + create mode 100644 components/adblock/core/converter/test/filter_keyword_extractor_test.cc + create mode 100644 components/adblock/core/converter/test/metadata_test.cc + create mode 100644 components/adblock/core/converter/test/mock_snippet_tokenizer.cc + create mode 100644 components/adblock/core/converter/test/mock_snippet_tokenizer.h + create mode 100644 components/adblock/core/converter/test/snippet_tokenizer_impl_test.cc + create mode 100644 components/adblock/core/features.cc + create mode 100644 components/adblock/core/features.h + create mode 100644 components/adblock/core/schema/filter_list_schema.fbs + create mode 100644 components/adblock/core/session_stats.h + create mode 100644 components/adblock/core/sitekey_storage.h + create mode 100644 components/adblock/core/sitekey_storage_impl.cc + create mode 100644 components/adblock/core/sitekey_storage_impl.h + create mode 100644 components/adblock/core/subscription/BUILD.gn + create mode 100644 components/adblock/core/subscription/domain_splitter.cc + create mode 100644 components/adblock/core/subscription/domain_splitter.h + create mode 100644 components/adblock/core/subscription/installed_subscription.cc + create mode 100644 components/adblock/core/subscription/installed_subscription.h + create mode 100644 components/adblock/core/subscription/installed_subscription_impl.cc + create mode 100644 components/adblock/core/subscription/installed_subscription_impl.h + create mode 100644 components/adblock/core/subscription/ongoing_subscription_request.h + create mode 100644 components/adblock/core/subscription/ongoing_subscription_request_impl.cc + create mode 100644 components/adblock/core/subscription/ongoing_subscription_request_impl.h + create mode 100644 components/adblock/core/subscription/preloaded_subscription_provider.h + create mode 100644 components/adblock/core/subscription/preloaded_subscription_provider_impl.cc + create mode 100644 components/adblock/core/subscription/preloaded_subscription_provider_impl.h + create mode 100644 components/adblock/core/subscription/subscription.cc + create mode 100644 components/adblock/core/subscription/subscription.h + create mode 100644 components/adblock/core/subscription/subscription_collection.h + create mode 100644 components/adblock/core/subscription/subscription_collection_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_collection_impl.h + create mode 100644 components/adblock/core/subscription/subscription_config.cc + create mode 100644 components/adblock/core/subscription/subscription_config.h + create mode 100644 components/adblock/core/subscription/subscription_downloader.h + create mode 100644 components/adblock/core/subscription/subscription_downloader_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_downloader_impl.h + create mode 100644 components/adblock/core/subscription/subscription_persistent_metadata.h + create mode 100644 components/adblock/core/subscription/subscription_persistent_metadata_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_persistent_metadata_impl.h + create mode 100644 components/adblock/core/subscription/subscription_persistent_storage.h + create mode 100644 components/adblock/core/subscription/subscription_persistent_storage_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_persistent_storage_impl.h + create mode 100644 components/adblock/core/subscription/subscription_service.h + create mode 100644 components/adblock/core/subscription/subscription_service_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_service_impl.h + create mode 100644 components/adblock/core/subscription/subscription_updater.h + create mode 100644 components/adblock/core/subscription/subscription_updater_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_updater_impl.h + create mode 100644 components/adblock/core/subscription/subscription_validator.cc + create mode 100644 components/adblock/core/subscription/subscription_validator.h + create mode 100644 components/adblock/core/subscription/subscription_validator_impl.cc + create mode 100644 components/adblock/core/subscription/subscription_validator_impl.h + create mode 100644 components/adblock/core/subscription/test/installed_subscription_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/mock_installed_subscription.cc + create mode 100644 components/adblock/core/subscription/test/mock_installed_subscription.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription_collection.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription_collection.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription_downloader.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription_downloader.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription_persistent_metadata.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription_persistent_metadata.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription_service.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription_service.h + create mode 100644 components/adblock/core/subscription/test/mock_subscription_updater.cc + create mode 100644 components/adblock/core/subscription/test/mock_subscription_updater.h + create mode 100644 components/adblock/core/subscription/test/ongoing_subscription_request_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/preloaded_subscription_provider_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_collection_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_downloader_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_persistent_metadata_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_persistent_storage_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_service_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_updater_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/subscription_validator_impl_test.cc + create mode 100644 components/adblock/core/subscription/test/url_keyword_extractor_test.cc + create mode 100644 components/adblock/core/subscription/url_keyword_extractor.cc + create mode 100644 components/adblock/core/subscription/url_keyword_extractor.h + create mode 100644 components/adblock/core/test/activeping_telemetry_topic_provider_test.cc + create mode 100644 components/adblock/core/test/adblock_controller_impl_test.cc + create mode 100644 components/adblock/core/test/adblock_controller_legacy_impl_test.cc + create mode 100644 components/adblock/core/test/adblock_telemetry_service_unittest.cc + create mode 100644 components/adblock/core/test/bundled_subscription_test.cc + create mode 100644 components/adblock/core/test/mock_adblock_controller.cc + create mode 100644 components/adblock/core/test/mock_adblock_controller.h + create mode 100644 components/adblock/core/test/mock_sitekey_storage.cc + create mode 100644 components/adblock/core/test/mock_sitekey_storage.h + create mode 100644 components/adblock/core/test/sitekey_storage_impl_test.cc + create mode 100644 components/adblock/docs/ad-filtering/README.md + create mode 100644 components/adblock/docs/ad-filtering/element-hiding-sequence.png + create mode 100644 components/adblock/docs/ad-filtering/element-hiding-sequence.txt + create mode 100644 components/adblock/docs/ad-filtering/element-hiding.md + create mode 100644 components/adblock/docs/ad-filtering/filter-lists.md + create mode 100644 components/adblock/docs/ad-filtering/request-filter-matching-sequence.png + create mode 100644 components/adblock/docs/ad-filtering/request_filter_matching_sequence.txt + create mode 100644 components/adblock/docs/ad-filtering/resource-filtering.md + create mode 100644 components/adblock/docs/ad-filtering/response-filter-matching-sequence.png + create mode 100644 components/adblock/docs/ad-filtering/response_filter_matching_sequence.txt + create mode 100644 components/adblock/docs/ad-filtering/snippets.md + create mode 100644 components/adblock/docs/adr/README.md + create mode 100644 components/adblock/docs/adr/consuming-full-filter-lists.md + create mode 100644 components/adblock/docs/adr/moving-user-counting-to-dedicated-service.md + create mode 100644 components/adblock/docs/adr/not-extending-subresource-filter.md + create mode 100644 components/adblock/docs/adr/storing-filter-lists-in-flatbuffers-format.md + create mode 100644 components/adblock/docs/data-collection/README.md + create mode 100644 components/adblock/docs/data-collection/user-counting.md + create mode 100644 components/adblock/docs/design-overview.md + create mode 100644 components/adblock/docs/developer-notes.md + create mode 100644 components/adblock/docs/initialization-sequence.png + create mode 100644 components/adblock/docs/initialization-sequence.txt + create mode 100644 components/adblock/docs/integration-how-to.md + create mode 100644 components/adblock/docs/settings/README.md + create mode 100644 components/adblock/docs/settings/user-setting-sequence.png + create mode 100644 components/adblock/docs/settings/user-setting-sequence.txt + create mode 100644 components/adblock/features.gni + create mode 100644 components/adblock_comparison/BUILD.gn + create mode 100644 components/adblock_comparison/libadblockplus_reference_database.cc + create mode 100644 components/adblock_comparison/libadblockplus_reference_database.h + create mode 100644 components/adblock_comparison/test_request_reader.cc + create mode 100644 components/adblock_comparison/test_request_reader.h + create mode 100644 components/adblock_comparison/verify_flatbuffer_adblocking.cc + create mode 100644 components/resources/adblock_resources.grdp + create mode 100644 components/resources/adblocking/.gitignore + create mode 100644 components/resources/adblocking/BUILD.gn + create mode 100644 components/resources/adblocking/anticv.txt + create mode 100644 components/resources/adblocking/easylist.txt + create mode 100644 components/resources/adblocking/elemhide.js + create mode 100644 components/resources/adblocking/elemhide_for_selector.jst + create mode 100644 components/resources/adblocking/elemhideemu.jst + create mode 100644 components/resources/adblocking/exceptionrules.txt + create mode 100755 components/resources/adblocking/update.sh + create mode 100644 components/test/data/adblock/anticv.txt + create mode 100644 components/test/data/adblock/easylist.txt + create mode 100644 components/test/data/adblock/exceptionrules.txt + create mode 100644 components/test/data/adblock/longurl.txt + create mode 100644 components/test/data/adblock/random_shuf_100.tsv.sqlite + create mode 100644 gclient/.gclient + create mode 100644 gclient/.gclient_ci_android + create mode 100644 gclient/.gclient_ci_linux + create mode 100644 gclient/.gclient_ci_windows + create mode 100755 tools/adblock/interdiff.py + create mode 100644 tools/perf/benchmarks/eyeo.py + create mode 100644 tools/perf/page_sets/eyeo_page_set.py + +diff --git a/DEPS b/DEPS +--- a/DEPS ++++ b/DEPS +@@ -180,6 +180,10 @@ vars = { + # flag is set True. + 'checkout_wpr_archives': False, + ++ # Eyeo WPR archives are kept separately from Chromium WPRs due to ++ # access restrictions (authenticated Google Cloud Storage). ++ 'checkout_eyeo_wpr_archives': False, ++ + # By default, do not check out WebKit for iOS, as it is not needed unless + # running against ToT WebKit rather than system WebKit. This can be overridden + # e.g. with custom_vars. +@@ -294,6 +298,8 @@ vars = { + 'checkout_rust_toolchain_deps': False, + + 'android_git': 'https://android.googlesource.com', ++ 'eyeo_distpartners_gitlab': 'https://gitlab.com/eyeo/distpartners', ++ 'eyeo_snippets_gitlab': 'https://gitlab.com/eyeo/snippets.git', + 'aomedia_git': 'https://aomedia.googlesource.com', + 'boringssl_git': 'https://boringssl.googlesource.com', + 'chromium_git': 'https://chromium.googlesource.com', +@@ -487,6 +493,11 @@ vars = { + # and whatever else without interference from each other. + 'ffmpeg_revision': 'fd5b30c4bcf95ee607caf47ef65c3b96210867a4', + ++ # Three lines of non-changing comments so that ++ # the commit queue can handle CLs rolling feed ++ # and whatever else without interference from each other. ++ 'eyeo_snippets_revision': 'v0.5.5', ++ + # If you change this, also update the libc++ revision in + # //buildtools/deps_revisions.gni. + 'libcxx_revision': '4218f3525ad438b22b0e173d963515a09d143398', +@@ -820,6 +831,10 @@ deps = { + 'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal', + }, + ++ 'src/components/resources/adblocking/snippets': { ++ 'url': Var('eyeo_snippets_gitlab') + '@' + Var('eyeo_snippets_revision'), ++ }, ++ + 'src/docs/website': { + 'url': Var('chromium_git') + '/website.git' + '@' + '5bef1125e998d33bfb101ac0da9a6bc445121955', + }, +@@ -964,6 +979,13 @@ deps = { + 'dep_type': 'cipd', + }, + ++ 'src/tools/perf/eyeo_data': { ++ 'condition': ++ 'checkout_eyeo_wpr_archives', ++ 'url': ++ Var('eyeo_distpartners_gitlab') + '/web-page-recordings.git@ec931d65bce04c273d4a4cb4950d2a7f7aa2f37f', ++ }, ++ + 'src/third_party/accessibility_test_framework': { + 'packages': [ + { +diff --git a/README.md b/README.md +--- a/README.md ++++ b/README.md +@@ -19,3 +19,15 @@ Android WebView, Ash). Even if these products have multiple executables, the + code should be in subdirectories of the product. + + If you found a bug, please file it at https://crbug.com/new. ++ ++ ++## Eyeo Chromium SDK ++ ++Eyeo Chromium SDK is a fork of the Chromium project that ++integrates ad-filtering capabilities. A big part of the functionality is ++implemented inside a component, to simplify the integration with other ++modifications to the browser. ++ ++The [component folder](components/adblock) contains most of the source code, ++as well as the changelog, license and technical documentation about ++architecture and integration steps. +diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h +--- a/base/trace_event/builtin_categories.h ++++ b/base/trace_event/builtin_categories.h +@@ -1,6 +1,10 @@ + // Copyright 2018 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #ifndef BASE_TRACE_EVENT_BUILTIN_CATEGORIES_H_ + #define BASE_TRACE_EVENT_BUILTIN_CATEGORIES_H_ +@@ -86,6 +90,7 @@ + X("exo") \ + X("extensions") \ + X("explore_sites") \ ++ X("eyeo") \ + X("FileSystem") \ + X("file_system_provider") \ + X("fledge") \ +diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh +--- a/build/install-build-deps.sh ++++ b/build/install-build-deps.sh +@@ -4,6 +4,10 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the ++# components/adblock/LICENSE file. ++ + # Script to install everything needed to build chromium (well, ideally, anyway) + # See https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md + +@@ -567,9 +571,11 @@ fi + if package_exists libinput-dev; then + dev_list="${dev_list} libinput-dev" + fi +-if package_exists snapcraft; then +- dev_list="${dev_list} snapcraft" +-fi ++#Do NOT install snapcraft, as it hangs inside Docker trying to connect to the ++#store and preventing automated package updates. ++#if package_exists snapcraft; then ++# dev_list="${dev_list} snapcraft" ++#fi + + # Cross-toolchain strip is needed for building the sysroots. + if package_exists binutils-arm-linux-gnueabihf; then +diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -1,6 +1,10 @@ + # Copyright 2014 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. ++ + + import("//build/android/resource_sizes.gni") + import("//build/config/android/config.gni") +@@ -282,6 +286,7 @@ if (current_toolchain == default_toolchain) { + "//chrome/browser/ui/android/toolbar:java_resources", + "//chrome/browser/ui/android/webid/internal:java_resources", + "//chrome/browser/ui/messages/android:java_resources", ++ "//components/adblock/android:java_resources", + "//components/autofill/android:autofill_java_resources", + "//components/autofill/android:autofill_payments_java_resources", + "//components/blocked_content/android:java_resources", +@@ -498,6 +503,7 @@ if (current_toolchain == default_toolchain) { + "//chrome/browser/webapps/android:java", + "//chrome/browser/webauthn/android:java", + "//chrome/browser/xsurface:java", ++ "//components/adblock/android:adblock_java", + "//components/autofill/android:autofill_java", + "//components/autofill/android:prefeditor_autofill_java", + "//components/autofill_assistant/android:public_dependencies_java", +@@ -1613,6 +1619,7 @@ if (current_toolchain == default_toolchain) { + "//chrome/test/android:chrome_java_integration_test_support", + "//chrome/test/android:chrome_java_test_pagecontroller", + "//chrome/test/android/test_trusted_web_activity:test_trusted_web_activity_java", ++ "//components/adblock/android:adblock_java_tests", + "//components/autofill/android:autofill_java", + "//components/autofill/android:prefeditor_autofill_java", + "//components/autofill_assistant/android:public_dependencies_java", +@@ -4193,6 +4200,7 @@ group("jni_headers") { + "//chrome/browser/ui/messages/android:jni_headers", + "//chrome/browser/util:jni_headers", + "//chrome/browser/webauthn/android:jni_headers", ++ "//components/adblock/android:jni_headers", + "//components/autofill_assistant/android:jni_headers", + "//components/autofill_assistant/android:jni_headers_public", + "//components/autofill_assistant/android:jni_headers_public_dependencies", +diff --git a/chrome/android/chrome_common_shared_library.gni b/chrome/android/chrome_common_shared_library.gni +--- a/chrome/android/chrome_common_shared_library.gni ++++ b/chrome/android/chrome_common_shared_library.gni +@@ -1,6 +1,10 @@ + # Copyright 2018 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. ++ + + import("//base/android/linker/config.gni") + import("//build/config/android/config.gni") +diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml +--- a/chrome/android/java/res/xml/main_preferences.xml ++++ b/chrome/android/java/res/xml/main_preferences.xml +@@ -3,6 +3,9 @@ + Copyright 2015 The Chromium Authors + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. ++ ++This source code is a part of eyeo Chromium SDK. ++Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. + --> + + ++ + + + + + + + +diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc +--- a/chrome/app/chrome_main_delegate.cc ++++ b/chrome/app/chrome_main_delegate.cc +@@ -1,6 +1,10 @@ + // Copyright 2012 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/app/chrome_main_delegate.h" + +@@ -40,6 +44,7 @@ + #include "base/trace_event/trace_event_impl.h" + #include "build/build_config.h" + #include "build/chromeos_buildflags.h" ++#include "chrome/browser/adblock/adblock_content_browser_client.h" + #include "chrome/browser/chrome_content_browser_client.h" + #include "chrome/browser/chrome_resource_bundle_helper.h" + #include "chrome/browser/defaults.h" +@@ -1666,7 +1671,7 @@ content::ContentClient* ChromeMainDelegate::CreateContentClient() { + content::ContentBrowserClient* + ChromeMainDelegate::CreateContentBrowserClient() { + chrome_content_browser_client_ = +- std::make_unique(); ++ std::make_unique(); + return chrome_content_browser_client_.get(); + } + +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -1,6 +1,9 @@ + # Copyright 2014 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. + + import("//base/allocator/allocator.gni") + import("//build/buildflag_header.gni") +@@ -149,6 +152,26 @@ static_library("browser") { + "accessibility/page_colors.h", + "accessibility/page_colors_factory.cc", + "accessibility/page_colors_factory.h", ++ "adblock/adblock_content_browser_client.cc", ++ "adblock/adblock_content_browser_client.h", ++ "adblock/adblock_controller_factory.cc", ++ "adblock/adblock_controller_factory.h", ++ "adblock/adblock_telemetry_service_factory.cc", ++ "adblock/adblock_telemetry_service_factory.h", ++ "adblock/content_security_policy_injector_factory.cc", ++ "adblock/content_security_policy_injector_factory.h", ++ "adblock/element_hider_factory.cc", ++ "adblock/element_hider_factory.h", ++ "adblock/resource_classification_runner_factory.cc", ++ "adblock/resource_classification_runner_factory.h", ++ "adblock/session_stats_factory.cc", ++ "adblock/session_stats_factory.h", ++ "adblock/sitekey_storage_factory.cc", ++ "adblock/sitekey_storage_factory.h", ++ "adblock/subscription_persistent_metadata_factory.cc", ++ "adblock/subscription_persistent_metadata_factory.h", ++ "adblock/subscription_service_factory.cc", ++ "adblock/subscription_service_factory.h", + "after_startup_task_utils.cc", + "after_startup_task_utils.h", + "app_mode/app_mode_utils.cc", +@@ -2045,6 +2068,7 @@ static_library("browser") { + "//chrome/common/notifications", + "//chrome/installer/util:with_no_strings", + "//chrome/services/speech/buildflags", ++ "//components/adblock/content:browser", + "//components/assist_ranker", + "//components/autofill/content/browser", + "//components/autofill/core/browser", +@@ -2535,6 +2559,10 @@ static_library("browser") { + if (is_android) { + sources += [ + "after_startup_task_utils_android.cc", ++ "android/adblock/adblock_jni.cc", ++ "android/adblock/adblock_jni.h", ++ "android/adblock/adblock_jni_factory.cc", ++ "android/adblock/adblock_jni_factory.h", + "android/android_theme_resources.h", + "android/autocomplete/tab_matcher_android.cc", + "android/autocomplete/tab_matcher_android.h", +@@ -3254,6 +3282,7 @@ static_library("browser") { + "webauthn/android/conditional_ui_delegate_android.cc", + "webauthn/android/conditional_ui_delegate_android.h", + ] ++ + public_deps += [ + "//chrome/android/features/dev_ui:buildflags", + "//components/image_fetcher/core", +diff --git a/chrome/browser/adblock/README.md b/chrome/browser/adblock/README.md +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/README.md +@@ -0,0 +1,3 @@ ++This folder contains the OS-agnostic, Chrome-specific source code of eyeo Chromium SDK. ++ ++For the full documentation, refer to [components/adblock](/components/adblock). +diff --git a/chrome/browser/adblock/adblock_content_browser_client.cc b/chrome/browser/adblock/adblock_content_browser_client.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_content_browser_client.cc +@@ -0,0 +1,365 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_content_browser_client.h" ++ ++#include "base/containers/unique_ptr_adapters.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/content_security_policy_injector_factory.h" ++#include "chrome/browser/adblock/element_hider_factory.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/adblock/sitekey_storage_factory.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser_navigator_params.h" ++#include "components/adblock/content/browser/adblock_url_loader_factory.h" ++#include "components/adblock/content/browser/resource_classification_runner.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_prefs.h" ++#include "components/adblock/core/subscription/subscription_service.h" ++#include "components/embedder_support/user_agent_utils.h" ++#include "components/prefs/pref_service.h" ++#include "content/public/browser/browser_task_traits.h" ++#include "content/public/browser/browser_thread.h" ++#include "content/public/browser/render_frame_host.h" ++#include "content/public/browser/render_process_host.h" ++#include "content/public/browser/render_view_host.h" ++#include "content/public/browser/web_contents.h" ++#include "mojo/public/cpp/bindings/self_owned_receiver.h" ++#include "services/network/public/mojom/websocket.mojom.h" ++#include "services/service_manager/public/cpp/binder_registry.h" ++#include "third_party/blink/public/common/loader/url_loader_throttle.h" ++ ++#ifdef EYEO_INTERCEPT_DEBUG_URL ++#include "components/adblock/content/browser/adblock_url_loader_factory_for_test.h" ++#endif ++ ++#if BUILDFLAG(ENABLE_EXTENSIONS) ++#include "chrome/browser/extensions/extension_util.h" ++#endif ++ ++namespace { ++ ++bool IsFilteringNeeded(content::RenderFrameHost* frame) { ++ if (frame) { ++ auto* profile = ++ Profile::FromBrowserContext(frame->GetProcess()->GetBrowserContext()); ++ if (profile) { ++ return adblock::SubscriptionServiceFactory::GetForBrowserContext(profile) ++ ->GetStatus() != adblock::FilteringStatus::Inactive; ++ } ++ } ++ return false; ++} ++ ++// Owns all of the AdblockURLLoaderFactory for a given Profile. ++class AdblockContextData : public base::SupportsUserData::Data { ++ public: ++ AdblockContextData(const AdblockContextData&) = delete; ++ AdblockContextData& operator=(const AdblockContextData&) = delete; ++ ~AdblockContextData() override = default; ++ ++ static void StartProxying( ++ Profile* profile, ++ content::RenderFrameHost* frame, ++ int render_process_id, ++ mojo::PendingReceiver receiver, ++ mojo::PendingRemote target_factory, ++ content::ContentBrowserClient::URLLoaderFactoryType type) { ++ const void* const kAdblockContextUserDataKey = &kAdblockContextUserDataKey; ++ auto* self = static_cast( ++ profile->GetUserData(kAdblockContextUserDataKey)); ++ if (!self) { ++ self = new AdblockContextData(); ++ profile->SetUserData(kAdblockContextUserDataKey, base::WrapUnique(self)); ++ } ++ auto* browser_context = ++ content::WebContents::FromRenderFrameHost(frame)->GetBrowserContext(); ++ adblock::AdblockURLLoaderFactoryConfig config{ ++ adblock::SubscriptionServiceFactory::GetForBrowserContext( ++ browser_context), ++ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext( ++ browser_context), ++ adblock::ElementHiderFactory::GetForBrowserContext(browser_context), ++ adblock::SitekeyStorageFactory::GetForBrowserContext(browser_context), ++ adblock::ContentSecurityPolicyInjectorFactory::GetForBrowserContext( ++ browser_context)}; ++#ifdef EYEO_INTERCEPT_DEBUG_URL ++ content::WebContents* wc = content::WebContents::FromRenderFrameHost(frame); ++ bool is_adblock_test_url = ++ (type == ++ content::ContentBrowserClient::URLLoaderFactoryType::kNavigation) && ++ wc->GetVisibleURL().is_valid() && ++ wc->GetVisibleURL().host() == ++ adblock::AdblockURLLoaderFactoryForTest::kAdblockDebugDataHostName; ++ if (is_adblock_test_url) { ++ auto proxy = std::make_unique( ++ std::move(config), render_process_id, frame->GetRoutingID(), ++ std::move(receiver), std::move(target_factory), ++ embedder_support::GetUserAgent(), ++ base::BindOnce(&AdblockContextData::RemoveProxy, ++ self->weak_factory_.GetWeakPtr()), ++ adblock::AdblockControllerFactory::GetForBrowserContext( ++ Profile::FromBrowserContext( ++ frame->GetProcess()->GetBrowserContext()))); ++ self->proxies_.emplace(std::move(proxy)); ++ return; ++ } ++#endif ++ auto proxy = std::make_unique( ++ std::move(config), render_process_id, frame->GetRoutingID(), ++ std::move(receiver), std::move(target_factory), ++ embedder_support::GetUserAgent(), ++ base::BindOnce(&AdblockContextData::RemoveProxy, ++ self->weak_factory_.GetWeakPtr())); ++ self->proxies_.emplace(std::move(proxy)); ++ } ++ ++ private: ++ void RemoveProxy(adblock::AdblockURLLoaderFactory* proxy) { ++ auto it = proxies_.find(proxy); ++ DCHECK(it != proxies_.end()); ++ proxies_.erase(it); ++ } ++ ++ AdblockContextData() = default; ++ ++ std::set, ++ base::UniquePtrComparator> ++ proxies_; ++ ++ base::WeakPtrFactory weak_factory_{this}; ++}; ++ ++} // namespace ++ ++AdblockContentBrowserClient::AdblockContentBrowserClient() = default; ++ ++AdblockContentBrowserClient::~AdblockContentBrowserClient() = default; ++ ++#if BUILDFLAG(ENABLE_EXTENSIONS) ++// static ++bool AdblockContentBrowserClient::force_adblock_proxy_for_testing_ = false; ++ ++// static ++void AdblockContentBrowserClient::ForceAdblockProxyForTesting() { ++ force_adblock_proxy_for_testing_ = true; ++} ++#endif ++ ++bool AdblockContentBrowserClient::CanCreateWindow( ++ content::RenderFrameHost* opener, ++ const GURL& opener_url, ++ const GURL& opener_top_level_frame_url, ++ const url::Origin& source_origin, ++ content::mojom::WindowContainerType container_type, ++ const GURL& target_url, ++ const content::Referrer& referrer, ++ const std::string& frame_name, ++ WindowOpenDisposition disposition, ++ const blink::mojom::WindowFeatures& features, ++ bool user_gesture, ++ bool opener_suppressed, ++ bool* no_javascript_access) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ DCHECK(opener); ++ ++ if (IsFilteringNeeded(opener)) { ++ content::WebContents* web_contents = ++ content::WebContents::FromRenderFrameHost(opener); ++ auto* subscription_service = ++ adblock::SubscriptionServiceFactory::GetForBrowserContext( ++ web_contents->GetBrowserContext()); ++ if (subscription_service->GetStatus() == adblock::FilteringStatus::Active) { ++ GURL popup_url(target_url); ++ web_contents->GetPrimaryMainFrame()->GetProcess()->FilterURL(false, ++ &popup_url); ++ auto* classification_runner = ++ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext( ++ web_contents->GetBrowserContext()); ++ // TODO(mpawlowski): Use entire Snapshot for classification, DPD-1568. ++ const auto popup_blocking_decision = ++ classification_runner->ShouldBlockPopup( ++ std::move(subscription_service->GetCurrentSnapshot()[0]), ++ opener_top_level_frame_url, popup_url, opener); ++ if (popup_blocking_decision == adblock::FilterMatchResult::kAllowRule) ++ return true; ++ if (popup_blocking_decision == adblock::FilterMatchResult::kBlockRule) ++ return false; ++ // Otherwise, if eyeo adblocking is disabled or there is no rule that ++ // explicitly allows or blocks a popup, fall back on Chromium's built-in ++ // popup blocker. ++ DCHECK(popup_blocking_decision == adblock::FilterMatchResult::kDisabled || ++ popup_blocking_decision == adblock::FilterMatchResult::kNoRule); ++ } ++ } ++ ++ return ChromeContentBrowserClient::CanCreateWindow( ++ opener, opener_url, opener_top_level_frame_url, source_origin, ++ container_type, target_url, referrer, frame_name, disposition, features, ++ user_gesture, opener_suppressed, no_javascript_access); ++} ++ ++bool AdblockContentBrowserClient::WillInterceptWebSocket( ++ content::RenderFrameHost* frame) { ++ if (IsFilteringNeeded(frame)) { ++ return true; ++ } ++ ++ return ChromeContentBrowserClient::WillInterceptWebSocket(frame); ++} ++ ++void AdblockContentBrowserClient::CreateWebSocket( ++ content::RenderFrameHost* frame, ++ WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client) { ++ if (IsFilteringNeeded(frame)) { ++ CreateWebSocketInternal(frame->GetGlobalId(), std::move(factory), url, ++ site_for_cookies, user_agent, ++ std::move(handshake_client)); ++ } else { ++ DCHECK(ChromeContentBrowserClient::WillInterceptWebSocket(frame)); ++ ChromeContentBrowserClient::CreateWebSocket(frame, std::move(factory), url, ++ site_for_cookies, user_agent, ++ std::move(handshake_client)); ++ } ++} ++ ++void AdblockContentBrowserClient::CreateWebSocketInternal( ++ content::GlobalRenderFrameHostId render_frame_host_id, ++ WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client) { ++ auto* frame = content::RenderFrameHost::FromID(render_frame_host_id); ++ if (!frame) ++ return; ++ auto* browser_context = frame->GetProcess()->GetBrowserContext(); ++ auto* subscription_service = ++ adblock::SubscriptionServiceFactory::GetForBrowserContext( ++ browser_context); ++ if (subscription_service->GetStatus() == ++ adblock::FilteringStatus::Initializing) { ++ subscription_service->RunWhenInitialized(base::BindOnce( ++ &AdblockContentBrowserClient::CreateWebSocketInternal, ++ weak_factory_.GetWeakPtr(), render_frame_host_id, std::move(factory), ++ url, site_for_cookies, user_agent, std::move(handshake_client))); ++ return; ++ } ++ auto* classification_runner = ++ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext( ++ browser_context); ++ // TODO(mpawlowski): Use entire Snapshot for classification, DPD-1568. ++ classification_runner->CheckRequestFilterMatchForWebSocket( ++ std::move(subscription_service->GetCurrentSnapshot()[0]), url, ++ render_frame_host_id, ++ base::BindOnce( ++ &AdblockContentBrowserClient::OnWebSocketFilterCheckCompleted, ++ weak_factory_.GetWeakPtr(), render_frame_host_id, std::move(factory), ++ url, site_for_cookies, user_agent, std::move(handshake_client))); ++} ++ ++void AdblockContentBrowserClient::OnWebSocketFilterCheckCompleted( ++ content::GlobalRenderFrameHostId render_frame_host_id, ++ ChromeContentBrowserClient::WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client, ++ adblock::FilterMatchResult result) { ++ auto* frame = content::RenderFrameHost::FromID(render_frame_host_id); ++ if (!frame) ++ return; ++ const bool has_blocking_filter = ++ result == adblock::FilterMatchResult::kBlockRule; ++ if (!has_blocking_filter) { ++ VLOG(1) << "[eyeo] Web socket allowed for " << url; ++ if (ChromeContentBrowserClient::WillInterceptWebSocket(frame)) { ++ ChromeContentBrowserClient::CreateWebSocket( ++ frame, std::move(factory), url, site_for_cookies, user_agent, ++ std::move(handshake_client)); ++ return; ++ } ++ ++ std::vector headers; ++ if (user_agent) { ++ headers.push_back(network::mojom::HttpHeader::New( ++ net::HttpRequestHeaders::kUserAgent, *user_agent)); ++ } ++ std::move(factory).Run(url, std::move(headers), std::move(handshake_client), ++ mojo::NullRemote(), mojo::NullRemote()); ++ } ++ ++ VLOG(1) << "[eyeo] Web socket blocked for " << url; ++} ++ ++bool AdblockContentBrowserClient::WillCreateURLLoaderFactory( ++ content::BrowserContext* browser_context, ++ content::RenderFrameHost* frame, ++ int render_process_id, ++ URLLoaderFactoryType type, ++ const url::Origin& request_initiator, ++ absl::optional navigation_id, ++ ukm::SourceIdObj ukm_source_id, ++ mojo::PendingReceiver* factory_receiver, ++ mojo::PendingRemote* ++ header_client, ++ bool* bypass_redirect_checks, ++ bool* disable_secure_dns, ++ network::mojom::URLLoaderFactoryOverridePtr* factory_override) { ++ // Create Chromium proxy first as WebRequestProxyingURLLoaderFactory logic ++ // depends on being first proxy ++ bool use_chrome_proxy = ++ ChromeContentBrowserClient::WillCreateURLLoaderFactory( ++ browser_context, frame, render_process_id, type, request_initiator, ++ navigation_id, ukm_source_id, factory_receiver, header_client, ++ bypass_redirect_checks, disable_secure_dns, factory_override); ++ auto* profile = frame ? Profile::FromBrowserContext( ++ frame->GetProcess()->GetBrowserContext()) ++ : nullptr; ++ ++#if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (!force_adblock_proxy_for_testing_ && ++ request_initiator.scheme() == extensions::kExtensionScheme) { ++ VLOG(1) << "[eyeo] Do not use adblock proxy for extensions requests " ++ "[extension id:" ++ << request_initiator.host() << "]."; ++ return use_chrome_proxy; ++ } ++#endif ++ ++ bool use_adblock_proxy = ++ (type == URLLoaderFactoryType::kDocumentSubResource || ++ type == URLLoaderFactoryType::kNavigation) && ++ IsFilteringNeeded(frame); ++ if (use_adblock_proxy) { ++ auto proxied_receiver = std::move(*factory_receiver); ++ mojo::PendingRemote target_factory_remote; ++ *factory_receiver = target_factory_remote.InitWithNewPipeAndPassReceiver(); ++ AdblockContextData::StartProxying(profile, frame, render_process_id, ++ std::move(proxied_receiver), ++ std::move(target_factory_remote), type); ++ } ++ return use_adblock_proxy || use_chrome_proxy; ++} +diff --git a/chrome/browser/adblock/adblock_content_browser_client.h b/chrome/browser/adblock/adblock_content_browser_client.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_content_browser_client.h +@@ -0,0 +1,110 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTENT_BROWSER_CLIENT_H_ ++#define CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTENT_BROWSER_CLIENT_H_ ++ ++#include "build/buildflag.h" ++#include "chrome/browser/chrome_content_browser_client.h" ++ ++namespace adblock { ++enum class FilterMatchResult; ++} // namespace adblock ++ ++/** ++ * @brief Intercepts network and UI events to inject ad-filtering. ++ * Provides ad-filtering implementations of URLLoaderThrottles. ++ * Binds a mojo connection between Renderer processes and the ++ * Browser-process-based ResourceClassificationRunner. ++ * Lives in browser process UI thread. ++ */ ++class AdblockContentBrowserClient : public ChromeContentBrowserClient { ++ public: ++ AdblockContentBrowserClient(); ++ ~AdblockContentBrowserClient() override; ++ ++#if BUILDFLAG(ENABLE_EXTENSIONS) ++ // Enable ad filtering also for requests initiated by extensions. ++ // This allows implementing extension-driven browser tests. ++ // In production code, requests from extensions are not blocked. ++ static void ForceAdblockProxyForTesting(); ++#endif ++ ++ bool CanCreateWindow(content::RenderFrameHost* opener, ++ const GURL& opener_url, ++ const GURL& opener_top_level_frame_url, ++ const url::Origin& source_origin, ++ content::mojom::WindowContainerType container_type, ++ const GURL& target_url, ++ const content::Referrer& referrer, ++ const std::string& frame_name, ++ WindowOpenDisposition disposition, ++ const blink::mojom::WindowFeatures& features, ++ bool user_gesture, ++ bool opener_suppressed, ++ bool* no_javascript_access) override; ++ bool WillInterceptWebSocket(content::RenderFrameHost* frame) override; ++ void CreateWebSocket( ++ content::RenderFrameHost* frame, ++ WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client) override; ++ bool WillCreateURLLoaderFactory( ++ content::BrowserContext* browser_context, ++ content::RenderFrameHost* frame, ++ int render_process_id, ++ URLLoaderFactoryType type, ++ const url::Origin& request_initiator, ++ absl::optional navigation_id, ++ ukm::SourceIdObj ukm_source_id, ++ mojo::PendingReceiver* factory_receiver, ++ mojo::PendingRemote* ++ header_client, ++ bool* bypass_redirect_checks, ++ bool* disable_secure_dns, ++ network::mojom::URLLoaderFactoryOverridePtr* factory_override) override; ++ ++ private: ++ void CreateWebSocketInternal( ++ content::GlobalRenderFrameHostId render_frame_host_id, ++ WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client); ++ void OnWebSocketFilterCheckCompleted( ++ content::GlobalRenderFrameHostId render_frame_host_id, ++ ChromeContentBrowserClient::WebSocketFactory factory, ++ const GURL& url, ++ const net::SiteForCookies& site_for_cookies, ++ const absl::optional& user_agent, ++ mojo::PendingRemote ++ handshake_client, ++ adblock::FilterMatchResult result); ++ ++ base::WeakPtrFactory weak_factory_{this}; ++ ++#if BUILDFLAG(ENABLE_EXTENSIONS) ++ static bool force_adblock_proxy_for_testing_; ++#endif ++}; ++ ++#endif // CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTENT_BROWSER_CLIENT_H_ +diff --git a/chrome/browser/adblock/adblock_content_browser_client_browsertest.cc b/chrome/browser/adblock/adblock_content_browser_client_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_content_browser_client_browsertest.cc +@@ -0,0 +1,122 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_content_browser_client.h" ++ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/browser/ui/browser_commands.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "components/adblock/core/common/adblock_prefs.h" ++#include "components/adblock/core/subscription/subscription_service.h" ++#include "components/adblock/core/subscription/test/mock_subscription_service.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++#include "net/test/spawned_test_server/spawned_test_server.h" ++#include "net/test/test_data_directory.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++namespace adblock { ++ ++class AdblockContentBrowserClientBrowserTest : public InProcessBrowserTest { ++ public: ++ void SetUpOnMainThread() override { ++ watcher_ = std::make_unique( ++ browser()->tab_strip_model()->GetActiveWebContents(), u"PASS"); ++ watcher_->AlsoWaitForTitle(u"FAIL"); ++ embedded_test_server()->ServeFilesFromSourceDirectory( ++ net::GetWebSocketTestDataDirectory()); ++ ASSERT_TRUE(embedded_test_server()->Start()); ++ } ++ ++ void TearDownOnMainThread() override { watcher_.reset(); } ++ ++ void NavigateToHTTP(const std::string& path) { ++ // Visit a HTTPS page for testing. ++ GURL::Replacements replacements; ++ replacements.SetSchemeStr("http"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL( ++ browser(), ws_server_.GetURL(path).ReplaceComponents(replacements))); ++ } ++ ++ std::string WaitAndGetTitle() { ++ return base::UTF16ToUTF8(watcher_->WaitAndGetTitle()); ++ } ++ ++ net::SpawnedTestServer ws_server_{net::SpawnedTestServer::TYPE_WS, ++ net::GetWebSocketTestDataDirectory()}; ++ ++ private: ++ std::unique_ptr watcher_; ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockContentBrowserClientBrowserTest, ++ WebSocketConnectionNotInterrupted) { ++ // Launch a WebSocket server. ++ ASSERT_TRUE(ws_server_.Start()); ++ ++ // Disable ad-filtering. ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()) ++ ->SetAdblockEnabled(false); ++ ++ NavigateToHTTP("split_packet_check.html"); ++ ++ // WebSocket connected. ++ EXPECT_EQ("PASS", WaitAndGetTitle()); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockContentBrowserClientBrowserTest, ++ WebSocketConnectionInterruptedButNotBlocked) { ++ // Launch a WebSocket server. ++ ASSERT_TRUE(ws_server_.Start()); ++ ++ // Enable ad-filtering. ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()) ++ ->SetAdblockEnabled(true); ++ ++ NavigateToHTTP("split_packet_check.html"); ++ ++ // WebSocket connected, there were no blocking filters. ++ EXPECT_EQ("PASS", WaitAndGetTitle()); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockContentBrowserClientBrowserTest, ++ WebSocketConnectionInterruptedAndBlocked) { ++ // Launch a WebSocket server. ++ ASSERT_TRUE(ws_server_.Start()); ++ ++ // Intercept WebSocket and block connection via a filter. ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->SetAdblockEnabled(true); ++ controller->RemoveCustomFilter(kAllowlistEverythingFilter); ++ controller->AddCustomFilter({"$websocket"}); ++ ++ NavigateToHTTP("split_packet_check.html"); ++ ++ // WebSocket did not connect. ++ EXPECT_EQ("FAIL", WaitAndGetTitle()); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_content_browser_client_unittest.cc b/chrome/browser/adblock/adblock_content_browser_client_unittest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_content_browser_client_unittest.cc +@@ -0,0 +1,278 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_content_browser_client.h" ++ ++#include "base/callback_list.h" ++#include "base/run_loop.h" ++#include "base/test/mock_callback.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/test/base/chrome_render_view_host_test_harness.h" ++#include "components/adblock/content/browser/test/mock_resource_classification_runner.h" ++#include "components/adblock/core/common/adblock_prefs.h" ++#include "components/adblock/core/common/content_type.h" ++#include "components/adblock/core/subscription/installed_subscription.h" ++#include "components/adblock/core/subscription/subscription_service.h" ++#include "components/adblock/core/subscription/test/mock_subscription_collection.h" ++#include "components/adblock/core/subscription/test/mock_subscription_service.h" ++#include "components/adblock/core/test/mock_adblock_controller.h" ++#include "components/keyed_service/core/keyed_service.h" ++#include "content/public/browser/content_browser_client.h" ++#include "content/public/test/mock_render_process_host.h" ++#include "content/public/test/test_renderer_host.h" ++#include "gmock/gmock.h" ++#include "services/network/public/mojom/network_context.mojom.h" ++#include "services/network/public/mojom/websocket.mojom.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++using testing::_; ++using testing::Return; ++ ++namespace adblock { ++namespace { ++ ++class DelayedInitSubscriptionService : public MockSubscriptionService { ++ public: ++ FilteringStatus GetStatus() const override { return status_; } ++ void RunWhenInitialized(base::OnceClosure task) override { ++ deferred_tasks_.AddUnsafe(std::move(task)); ++ } ++ ++ void InitializeNow() { ++ status_ = FilteringStatus::Active; ++ deferred_tasks_.Notify(); ++ } ++ ++ FilteringStatus status_ = FilteringStatus::Initializing; ++ base::OnceClosureList deferred_tasks_; ++}; ++ ++} // namespace ++ ++class AdblockContentBrowserClientUnitTest ++ : public ChromeRenderViewHostTestHarness { ++ public: ++ TestingProfile::TestingFactories GetTestingFactories() const override { ++ return {std::make_pair( ++ SubscriptionServiceFactory::GetInstance(), ++ base::BindRepeating([](content::BrowserContext* bc) ++ -> std::unique_ptr { ++ return std::make_unique(); ++ })), ++ std::make_pair( ++ ResourceClassificationRunnerFactory::GetInstance(), ++ base::BindRepeating([](content::BrowserContext* bc) ++ -> std::unique_ptr { ++ return std::make_unique(); ++ }))}; ++ } ++ ++ void SetUp() override { ++ RenderViewHostTestHarness::SetUp(); ++ ++ subscription_service_ = static_cast( ++ SubscriptionServiceFactory::GetForBrowserContext(profile())); ++ resource_classification_runner_ = ++ static_cast( ++ ResourceClassificationRunnerFactory::GetForBrowserContext( ++ profile())); ++ } ++ ++ DelayedInitSubscriptionService* subscription_service_; ++ MockResourceClassificationRunner* resource_classification_runner_; ++}; ++ ++TEST_F(AdblockContentBrowserClientUnitTest, ++ WillInterceptWebSocketWhenFilteringActive) { ++ AdblockContentBrowserClient content_client; ++ subscription_service_->status_ = FilteringStatus::Inactive; ++ EXPECT_FALSE(content_client.WillInterceptWebSocket(main_rfh())); ++ subscription_service_->status_ = FilteringStatus::Initializing; ++ EXPECT_TRUE(content_client.WillInterceptWebSocket(main_rfh())); ++ subscription_service_->status_ = FilteringStatus::Active; ++ EXPECT_TRUE(content_client.WillInterceptWebSocket(main_rfh())); ++} ++ ++TEST_F(AdblockContentBrowserClientUnitTest, ++ RenderFrameHostDiesBeforeSubscriptionServiceInitialized) { ++ AdblockContentBrowserClient content_client; ++ ++ base::MockCallback ++ web_socket_factory; ++ // The web_socket_factory callback will never be called because the associated ++ // RenderFrameHost will be dead. ++ EXPECT_CALL(web_socket_factory, Run(_, _, _, _, _)).Times(0); ++ ++ // In case the resource classification proceeds, let it finish to expose ++ // potential use-after-free. ++ ON_CALL(*subscription_service_, GetCurrentSnapshot()).WillByDefault([]() { ++ SubscriptionService::Snapshot snapshot; ++ snapshot.push_back(std::make_unique()); ++ return snapshot; ++ }); ++ ++ ON_CALL(*resource_classification_runner_, ++ CheckRequestFilterMatchForWebSocket(_, _, _, _)) ++ .WillByDefault([&](auto subscription_collection, const auto& url, ++ auto rfh_id, auto callback) { ++ std::move(callback).Run(FilterMatchResult::kAllowRule); ++ }); ++ ++ const net::SiteForCookies site_for_cookies; ++ content_client.CreateWebSocket(main_rfh(), web_socket_factory.Get(), ++ GURL("wss://domain.com/test"), ++ site_for_cookies, absl::nullopt, {}); ++ // Tab is closed. ++ DeleteContents(); ++ ++ // SubscriptionService becomes initialized, triggers deferred classification ++ // of web socket. This does nothing. ++ subscription_service_->InitializeNow(); ++ ++ task_environment()->RunUntilIdle(); ++} ++ ++TEST_F(AdblockContentBrowserClientUnitTest, ++ RenderFrameHostDiesBeforeClassificationFinished) { ++ const auto kSocketUrl = GURL("wss://domain.com/test"); ++ // SubscriptionService is initialized from the start. ++ subscription_service_->InitializeNow(); ++ // It will be queried for a SubscriptionCollection to classify the web socket ++ // connection. ++ EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { ++ SubscriptionService::Snapshot snapshot; ++ snapshot.push_back(std::make_unique()); ++ return snapshot; ++ }); ++ // The SubscriptionCollection will be passed to ResourceClassificationRunner ++ // to run the classification asynchronously. Save the callback to run it ++ // later. ++ CheckFilterMatchCallback classification_callback; ++ EXPECT_CALL(*resource_classification_runner_, ++ CheckRequestFilterMatchForWebSocket(_, kSocketUrl, ++ main_rfh()->GetGlobalId(), _)) ++ .WillOnce([&](auto subscription_collection, const auto& url, auto rfh_id, ++ auto callback) { ++ classification_callback = std::move(callback); ++ }); ++ ++ AdblockContentBrowserClient content_client; ++ base::MockCallback ++ web_socket_factory; ++ // The web_socket_factory callback will never be called because the associated ++ // RenderFrameHost will be dead. ++ EXPECT_CALL(web_socket_factory, Run(_, _, _, _, _)).Times(0); ++ ++ const net::SiteForCookies site_for_cookies; ++ content_client.CreateWebSocket(main_rfh(), web_socket_factory.Get(), ++ kSocketUrl, site_for_cookies, absl::nullopt, ++ {}); ++ // Tab is closed. ++ DeleteContents(); ++ ++ // Classification finishes now. It will not trigger a call to ++ // |web_socket_factory| because the RFH is dead. ++ std::move(classification_callback).Run(FilterMatchResult::kBlockRule); ++ ++ task_environment()->RunUntilIdle(); ++} ++ ++TEST_F(AdblockContentBrowserClientUnitTest, WebSocketAllowed) { ++ const auto kSocketUrl = GURL("wss://domain.com/test"); ++ // SubscriptionService is initialized from the start. ++ subscription_service_->InitializeNow(); ++ // It will be queried for a SubscriptionCollection to classify the web socket ++ // connection. ++ EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { ++ SubscriptionService::Snapshot snapshot; ++ snapshot.push_back(std::make_unique()); ++ return snapshot; ++ }); ++ // The SubscriptionCollection will be passed to ResourceClassificationRunner ++ // to run the classification asynchronously. Save the callback to run it ++ // later. ++ CheckFilterMatchCallback classification_callback; ++ EXPECT_CALL(*resource_classification_runner_, ++ CheckRequestFilterMatchForWebSocket(_, kSocketUrl, ++ main_rfh()->GetGlobalId(), _)) ++ .WillOnce([&](auto subscription_collection, const auto& url, auto rfh_id, ++ auto callback) { ++ classification_callback = std::move(callback); ++ }); ++ ++ AdblockContentBrowserClient content_client; ++ base::MockCallback ++ web_socket_factory; ++ // The web_socket_factory callback will be called to let the web socket ++ // continue connecting. ++ EXPECT_CALL(web_socket_factory, Run(kSocketUrl, _, _, _, _)); ++ ++ const net::SiteForCookies site_for_cookies; ++ content_client.CreateWebSocket(main_rfh(), web_socket_factory.Get(), ++ kSocketUrl, site_for_cookies, absl::nullopt, ++ {}); ++ ++ // Classification finishes now. It will trigger a call to |web_socket_factory| ++ std::move(classification_callback).Run(FilterMatchResult::kAllowRule); ++ ++ task_environment()->RunUntilIdle(); ++} ++ ++TEST_F(AdblockContentBrowserClientUnitTest, WebSocketBlocked) { ++ const auto kSocketUrl = GURL("wss://domain.com/test"); ++ // SubscriptionService is initialized from the start. ++ subscription_service_->InitializeNow(); ++ // It will be queried for a SubscriptionCollection to classify the web socket ++ // connection. ++ EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { ++ SubscriptionService::Snapshot snapshot; ++ snapshot.push_back(std::make_unique()); ++ return snapshot; ++ }); ++ // The SubscriptionCollection will be passed to ResourceClassificationRunner ++ // to run the classification asynchronously. Save the callback to run it ++ // later. ++ CheckFilterMatchCallback classification_callback; ++ EXPECT_CALL(*resource_classification_runner_, ++ CheckRequestFilterMatchForWebSocket(_, kSocketUrl, ++ main_rfh()->GetGlobalId(), _)) ++ .WillOnce([&](auto subscription_collection, const auto& url, auto rfh_id, ++ auto callback) { ++ classification_callback = std::move(callback); ++ }); ++ ++ AdblockContentBrowserClient content_client; ++ base::MockCallback ++ web_socket_factory; ++ // The web_socket_factory callback will not be called as to disallow ++ // connection. ++ EXPECT_CALL(web_socket_factory, Run(kSocketUrl, _, _, _, _)).Times(0); ++ ++ const net::SiteForCookies site_for_cookies; ++ content_client.CreateWebSocket(main_rfh(), web_socket_factory.Get(), ++ kSocketUrl, site_for_cookies, absl::nullopt, ++ {}); ++ ++ // Classification finishes now. ++ std::move(classification_callback).Run(FilterMatchResult::kBlockRule); ++ ++ task_environment()->RunUntilIdle(); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_controller_factory.cc b/chrome/browser/adblock/adblock_controller_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_controller_factory.cc +@@ -0,0 +1,115 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++ ++#include ++ ++#include "base/command_line.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/browser_process.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/core/adblock_controller_impl.h" ++#include "components/adblock/core/adblock_controller_legacy_impl.h" ++#include "components/adblock/core/adblock_switches.h" ++#include "components/adblock/core/common/adblock_prefs.h" ++#include "components/adblock/core/configuration/persistent_filtering_configuration.h" ++#include "components/adblock/core/subscription/subscription_config.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "components/pref_registry/pref_registry_syncable.h" ++#include "components/version_info/version_info.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++AdblockController* AdblockControllerFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++AdblockControllerFactory* AdblockControllerFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++AdblockControllerFactory::AdblockControllerFactory() ++ : BrowserContextKeyedServiceFactory( ++ "AdblockController", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(SubscriptionServiceFactory::GetInstance()); ++} ++ ++AdblockControllerFactory::~AdblockControllerFactory() = default; ++ ++KeyedService* AdblockControllerFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ auto* prefs = Profile::FromBrowserContext(context)->GetPrefs(); ++ auto adblock_filtering_configuration = ++ std::make_unique(prefs, "adblock"); ++ ++ if (base::CommandLine::ForCurrentProcess()->HasSwitch( ++ adblock::switches::kDisableAcceptableAds)) { ++ adblock_filtering_configuration->RemoveFilterList(AcceptableAdsUrl()); ++ } ++ if (base::CommandLine::ForCurrentProcess()->HasSwitch( ++ switches::kDisableAdblock)) { ++ adblock_filtering_configuration->SetEnabled(false); ++ } ++ ++ auto* subscription_service = ++ SubscriptionServiceFactory::GetForBrowserContext(context); ++ std::unique_ptr controller; ++ if (version_info::GetMajorVersionNumberAsInt() >= 111 || ++ base::CommandLine::ForCurrentProcess()->HasSwitch( ++ switches::kDisableWebUiCompatibility)) { ++ auto new_controller = std::make_unique( ++ adblock_filtering_configuration.get(), subscription_service, ++ g_browser_process->GetApplicationLocale(), ++ config::GetKnownSubscriptions()); ++ new_controller->RunFirstRunLogic(prefs); ++ new_controller->MigrateLegacyPrefs(prefs); ++ controller = std::move(new_controller); ++ } else { ++ auto legacy_controller = std::make_unique( ++ prefs, adblock_filtering_configuration.get(), subscription_service, ++ g_browser_process->GetApplicationLocale(), ++ config::GetKnownSubscriptions()); ++ legacy_controller->ReadStateFromPrefs(); ++ legacy_controller->RunFirstRunLogic(prefs); ++ controller = std::move(legacy_controller); ++ } ++ ++ subscription_service->InstallFilteringConfiguration( ++ std::move(adblock_filtering_configuration)); ++ ++ return controller.release(); ++} ++ ++content::BrowserContext* AdblockControllerFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++void AdblockControllerFactory::RegisterProfilePrefs( ++ user_prefs::PrefRegistrySyncable* registry) { ++ adblock::prefs::RegisterProfilePrefs(registry); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_controller_factory.h b/chrome/browser/adblock/adblock_controller_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_controller_factory.h +@@ -0,0 +1,50 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTROLLER_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTROLLER_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class AdblockController; ++class AdblockControllerFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ static AdblockController* GetForBrowserContext( ++ content::BrowserContext* context); ++ static AdblockControllerFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ AdblockControllerFactory(); ++ ~AdblockControllerFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++ void RegisterProfilePrefs( ++ user_prefs::PrefRegistrySyncable* registry) override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_ADBLOCK_CONTROLLER_FACTORY_H_ +diff --git a/chrome/browser/adblock/adblock_debug_url_browsertest.cc b/chrome/browser/adblock/adblock_debug_url_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_debug_url_browsertest.cc +@@ -0,0 +1,116 @@ ++// This file is part of eyeo Chromium SDK, ++// Copyright (C) 2006-present eyeo GmbH ++// ++// eyeo Chromium SDK is free software: you can redistribute it and/or modify ++// it under the terms of the GNU General Public License version 3 as ++// published by the Free Software Foundation. ++// ++// eyeo Chromium SDK is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with eyeo Chromium SDK. If not, see . ++ ++#include ++ ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/content/browser/adblock_url_loader_factory_for_test.h" ++#include "content/public/test/browser_test.h" ++#include "testing/gmock/include/gmock/gmock.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++using testing::_; ++using testing::Mock; ++using testing::Return; ++ ++namespace { ++ ++class AdblockDebugUrlTest : public InProcessBrowserTest { ++ public: ++ AdblockDebugUrlTest() {} ++ ~AdblockDebugUrlTest() override = default; ++ AdblockDebugUrlTest(const AdblockDebugUrlTest&) = delete; ++ AdblockDebugUrlTest& operator=(const AdblockDebugUrlTest&) = delete; ++ ++ protected: ++ std::string ExecuteScriptAndExtractString(const std::string& js_code) const { ++ content::WebContents* web_contents = ++ browser()->tab_strip_model()->GetActiveWebContents(); ++ return content::EvalJs(web_contents->GetPrimaryMainFrame(), js_code) ++ .ExtractString(); ++ } ++ ++ static constexpr char kReadPageBodyScript[] = R"( ++ document.getElementsByTagName('body')[0].firstChild.innerHTML ++ )"; ++ ++ const std::string kAdblockDebugUrl = ++ "http://" + ++ adblock::AdblockURLLoaderFactoryForTest::kAdblockDebugDataHostName; ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockDebugUrlTest, TestInvalidUrls) { ++ GURL invalid_command_url(kAdblockDebugUrl + "/some_invalid_command"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), invalid_command_url)); ++ ASSERT_EQ("INVALID_COMMAND", ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL invalid_payload_url1(kAdblockDebugUrl + "/add?wrong_param=value"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), invalid_payload_url1)); ++ ASSERT_EQ("INVALID_PAYLOAD", ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL invalid_payload_url2(kAdblockDebugUrl + "/add?wrongpayload=value"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), invalid_payload_url2)); ++ ASSERT_EQ("INVALID_PAYLOAD", ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL invalid_payload_url3(kAdblockDebugUrl + "/add?payload="); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), invalid_payload_url3)); ++ ASSERT_EQ("INVALID_PAYLOAD", ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockDebugUrlTest, TestValidUrls) { ++ GURL clear_filters_url(kAdblockDebugUrl + "/clear"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), clear_filters_url)); ++ ASSERT_EQ("OK", ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL list_filters_url(kAdblockDebugUrl + "/list"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), list_filters_url)); ++ std::string expected_no_filters = "OK"; ++ ASSERT_EQ(expected_no_filters, ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL add_filters_url(kAdblockDebugUrl + ++ "/add?payload=%2FadsPlugin%2F%2A%0A%2Fadsponsor."); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), add_filters_url)); ++ ASSERT_EQ("OK", ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), list_filters_url)); ++ std::string expected_two_filters = "OK\n\n/adsPlugin/*\n/adsponsor.\n"; ++ ASSERT_EQ(expected_two_filters, ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ GURL remove_filter_url(kAdblockDebugUrl + "/remove?payload=%2Fadsponsor."); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), remove_filter_url)); ++ ASSERT_EQ("OK", ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), list_filters_url)); ++ std::string expected_one_filter = "OK\n\n/adsPlugin/*\n"; ++ ASSERT_EQ(expected_one_filter, ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), clear_filters_url)); ++ ASSERT_EQ("OK", ExecuteScriptAndExtractString(kReadPageBodyScript)); ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), list_filters_url)); ++ ASSERT_EQ(expected_no_filters, ++ ExecuteScriptAndExtractString(kReadPageBodyScript)); ++} ++ ++} // namespace +diff --git a/chrome/browser/adblock/adblock_filter_list_browsertest.cc b/chrome/browser/adblock/adblock_filter_list_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_filter_list_browsertest.cc +@@ -0,0 +1,215 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "components/adblock/core/adblock_switches.h" ++#include "components/adblock/core/subscription/subscription_config.h" ++#include "components/version_info/version_info.h" ++#include "content/public/browser/browser_task_traits.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++ ++namespace adblock { ++ ++class AdblockFilterListDownloadTestBase : public InProcessBrowserTest { ++ public: ++ AdblockFilterListDownloadTestBase() ++ : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} ++ // We need to set server and request handler asap ++ void SetUpInProcessBrowserTestFixture() override { ++ InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); ++ host_resolver()->AddRule("easylist-downloads.adblockplus.org", "127.0.0.1"); ++ https_server_.RegisterRequestHandler( ++ base::BindRepeating(&AdblockFilterListDownloadTestBase::RequestHandler, ++ base::Unretained(this))); ++ net::EmbeddedTestServer::ServerCertificateConfig cert_config; ++ cert_config.dns_names = {"easylist-downloads.adblockplus.org"}; ++ https_server_.SetSSLConfig(cert_config); ++ ASSERT_TRUE(https_server_.Start()); ++ SetFilterListServerPortForTesting(https_server_.port()); ++ } ++ ++ void CheckRequestParams(const net::test_server::HttpRequest& request, ++ std::string expected_disabled_value) { ++ std::string os; ++ base::ReplaceChars(version_info::GetOSType(), base::kWhitespaceASCII, "", ++ &os); ++ EXPECT_TRUE(request.relative_url.find("addonName=eyeo-chromium-sdk") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("addonVersion=1.0") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("platformVersion=1.0") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("platform=" + os) != ++ std::string::npos); ++ EXPECT_TRUE( ++ request.relative_url.find("disabled=" + expected_disabled_value) != ++ std::string::npos); ++ } ++ ++ virtual std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) { ++ if (request.method == net::test_server::HttpMethod::METHOD_GET && ++ (base::StartsWith(request.relative_url, "/abp-filters-anti-cv.txt") || ++ base::StartsWith(request.relative_url, "/easylist.txt") || ++ base::StartsWith(request.relative_url, "/exceptionrules.txt"))) { ++ CheckRequestParams(request, "false"); ++ default_lists_.insert(request.relative_url.substr( ++ 1, request.relative_url.find_first_of("?") - 1)); ++ } ++ ++ // Unhandled requests result in the Embedded test server sending a 404. ++ return nullptr; ++ } ++ ++ void CloseBrowserFromAnyThread() { ++ content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING}) ++ ->PostTask( ++ FROM_HERE, ++ base::BindOnce( ++ &AdblockFilterListDownloadTestBase::CloseBrowserAsynchronously, ++ base::Unretained(this), browser())); ++ } ++ ++ protected: ++ net::EmbeddedTestServer https_server_; ++ std::set default_lists_; ++}; ++ ++class AdblockEnabledFilterListDownloadTest ++ : public AdblockFilterListDownloadTestBase { ++ public: ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) override { ++ auto return_value = ++ AdblockFilterListDownloadTestBase::RequestHandler(request); ++ // If we get all expected requests we simply finish the test by closing ++ // the browser, otherwise test will fail with a timeout. ++ if (default_lists_.size() == 3) { ++ CloseBrowserFromAnyThread(); ++ } ++ ++ return return_value; ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockEnabledFilterListDownloadTest, ++ TestInitialDownloads) { ++ RunUntilBrowserProcessQuits(); ++} ++ ++class AdblockEnabledAcceptableAdsDisabledFilterListDownloadTest ++ : public AdblockFilterListDownloadTestBase { ++ public: ++ AdblockEnabledAcceptableAdsDisabledFilterListDownloadTest() { ++ const auto testing_interval = base::Seconds(1); ++ SubscriptionServiceFactory::SetUpdateCheckAndDelayIntervalsForTesting( ++ testing_interval, testing_interval); ++ } ++ ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) override { ++ // If we get expected HEAD request we simply finish the test by closing ++ // the browser, otherwise test will fail with a timeout. ++ if (request.method == net::test_server::HttpMethod::METHOD_HEAD && ++ base::StartsWith(request.relative_url, "/exceptionrules.txt")) { ++ CheckRequestParams(request, "true"); ++ CloseBrowserFromAnyThread(); ++ } ++ ++ return nullptr; ++ } ++ ++ void SetUpCommandLine(base::CommandLine* command_line) override { ++ command_line->AppendSwitch(adblock::switches::kDisableAcceptableAds); ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F( ++ AdblockEnabledAcceptableAdsDisabledFilterListDownloadTest, ++ TestInitialDownloads) { ++ RunUntilBrowserProcessQuits(); ++} ++ ++class AdblockDisabledFilterListDownloadTest ++ : public AdblockFilterListDownloadTestBase { ++ public: ++ void SetUpCommandLine(base::CommandLine* command_line) override { ++ command_line->AppendSwitch(adblock::switches::kDisableAdblock); ++ } ++ ++ void VerifyNoDownloads() { ++ ASSERT_EQ(0u, default_lists_.size()); ++ CloseBrowserFromAnyThread(); ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockDisabledFilterListDownloadTest, ++ TestInitialDownloads) { ++ // This test assumes that inital downloads (for adblock enabled) will happen ++ // within 10 seconds. When tested locally it always happens within 3 seconds. ++ base::OneShotTimer timer; ++ timer.Start( ++ FROM_HERE, base::Seconds(10), ++ base::BindOnce(&AdblockDisabledFilterListDownloadTest::VerifyNoDownloads, ++ base::Unretained(this))); ++ RunUntilBrowserProcessQuits(); ++} ++ ++#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ++class AdblockPtLocaleFilterListDownloadTest ++ : public AdblockFilterListDownloadTestBase { ++ public: ++ AdblockPtLocaleFilterListDownloadTest() ++ : AdblockFilterListDownloadTestBase() { ++ setenv("LANGUAGE", "pt_PT", 1); ++ } ++ ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) override { ++ EXPECT_FALSE(base::StartsWith(request.relative_url, "/easylist.txt")); ++ if (request.method == net::test_server::HttpMethod::METHOD_GET && ++ (base::StartsWith(request.relative_url, "/abp-filters-anti-cv.txt") || ++ base::StartsWith(request.relative_url, ++ "/easylistportuguese+easylist.txt") || ++ base::StartsWith(request.relative_url, "/exceptionrules.txt"))) { ++ CheckRequestParams(request, "false"); ++ default_lists_.insert(request.relative_url.substr( ++ 1, request.relative_url.find_first_of("?") - 1)); ++ } ++ ++ // If we get all expected requests we simply finish the test by closing ++ // the browser, otherwise test will fail with a timeout. ++ if (default_lists_.size() == 3) { ++ CloseBrowserFromAnyThread(); ++ } ++ ++ // Unhandled requests result in the Embedded test server sending a 404. ++ return nullptr; ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockPtLocaleFilterListDownloadTest, ++ TestInitialDownloads) { ++ RunUntilBrowserProcessQuits(); ++} ++#endif ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_frame_hierarchy_builder_browsertest.cc b/chrome/browser/adblock/adblock_frame_hierarchy_builder_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_frame_hierarchy_builder_browsertest.cc +@@ -0,0 +1,123 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "components/adblock/content/browser/frame_hierarchy_builder.h" ++ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++namespace adblock { ++ ++// Simulated setup: ++// http://outer.com/outermost_frame.html ++// has an iframe: http://middle.com/middle_frame.html ++// has an iframe: http://inner.com/innermost_frame.html ++// has a subresource http://inner.com/resource.png ++// ++// All of these files are in chrome/test/data/adblock. Cross-domain distribution ++// is simulated via SetupCrossSiteRedirector. ++// innermost_frame.html reports whether resource.png is visible via ++// window.top.postMessage to outermost_frame.html, which stores a global ++// subresource_visible JS variable. ++class AdblockFrameHierarchyBrowserTest : public InProcessBrowserTest { ++ public: ++ void SetUpOnMainThread() override { ++ host_resolver()->AddRule("*", "127.0.0.1"); ++ embedded_test_server()->ServeFilesFromSourceDirectory( ++ "chrome/test/data/adblock"); ++ content::SetupCrossSiteRedirector(embedded_test_server()); ++ ASSERT_TRUE(embedded_test_server()->Start()); ++ } ++ ++ void SetFilters(std::vector filters) { ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->RemoveCustomFilter(kAllowlistEverythingFilter); ++ for (auto& filter : filters) { ++ controller->AddCustomFilter(filter); ++ } ++ } ++ ++ void NavigateToOutermostFrame() { ++ ASSERT_TRUE(ui_test_utils::NavigateToURL( ++ browser(), embedded_test_server()->GetURL( ++ "/cross-site/outer.com/outermost_frame.html"))); ++ } ++ ++ void VerifyTargetResourceShown(bool expected_shown) { ++ EXPECT_EQ( ++ expected_shown, ++ content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(), ++ "subresource_visible === true")); ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, ++ SubresourceShownWithNoFilters) { ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(true); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, SubresourceBlocked) { ++ SetFilters({"/resource.png"}); ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(false); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, ++ SubresourceAllowedViaInnerFrame) { ++ SetFilters({"/resource.png", "@@||inner.com^$document"}); ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(true); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, ++ SubresourceAllowedViaMiddleFrame) { ++ SetFilters({"/resource.png", "@@||middle.com^$document"}); ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(true); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, ++ SubresourceAllowedViaOutermostFrame) { ++ SetFilters({"/resource.png", "@@||outer.com^$document"}); ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(true); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockFrameHierarchyBrowserTest, ++ SubresourceBlockedWhenInvalidAllowRule) { ++ SetFilters({"/resource.png", "@@||bogus.com^$document"}); ++ NavigateToOutermostFrame(); ++ VerifyTargetResourceShown(false); ++} ++ ++// More tests can be added / parametrized, e.g.: ++// - elemhide blocking filters (in conjunction with $elemhide allow rules) ++// - $subdocument-based allow rules ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_multiple_tabs_browsertests.cc b/chrome/browser/adblock/adblock_multiple_tabs_browsertests.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_multiple_tabs_browsertests.cc +@@ -0,0 +1,156 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/browser/ui/browser_list.h" ++#include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/content/browser/resource_classification_runner.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "components/sessions/content/session_tab_helper.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++ ++namespace adblock { ++ ++class AdblockMultipleTabsBrowserTest ++ : public InProcessBrowserTest, ++ public ResourceClassificationRunner::Observer { ++ public: ++ void SetUpOnMainThread() override { ++ host_resolver()->AddRule(kTestDomain, "127.0.0.1"); ++ embedded_test_server()->ServeFilesFromSourceDirectory( ++ "chrome/test/data/adblock"); ++ ASSERT_TRUE(embedded_test_server()->Start()); ++ ResourceClassificationRunnerFactory::GetForBrowserContext( ++ browser()->profile()) ++ ->AddObserver(this); ++ // expected.png is allowlisted by allowlisted parent empty.html iframe ++ SetFilters({"blocked.png", "expected.png", "@@/empty.html^$document"}); ++ } ++ ++ void TearDownInProcessBrowserTestFixture() override { ++ ASSERT_EQ(kTabsCount, static_cast(tabs_with_blocked_resource_.size())); ++ ASSERT_EQ(kTabsCount, static_cast(tabs_with_allowed_resource_.size())); ++ } ++ ++ void SetFilters(std::vector filters) { ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->RemoveCustomFilter(kAllowlistEverythingFilter); ++ for (auto& filter : filters) { ++ controller->AddCustomFilter(filter); ++ } ++ } ++ ++ void RestoreTabs(Browser* browser) { ++ content::DOMMessageQueue queue; ++ RecentTabsSubMenuModel menu(nullptr, browser); ++ menu.ExecuteCommand(menu.GetFirstRecentTabsCommandId(), 0); ++ for (int i = 0; i < kTabsCount; ++i) { ++ std::string message; ++ EXPECT_TRUE(queue.WaitForMessage(&message)); ++ EXPECT_EQ("\"READY\"", message); ++ } ++ } ++ ++ // ResourceClassificationRunner::Observer: ++ void OnAdMatched(const GURL& url, ++ FilterMatchResult match_result, ++ const std::vector& parent_frame_urls, ++ ContentType content_type, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override { ++ const content::WebContents* wc = ++ content::WebContents::FromRenderFrameHost(render_frame_host); ++ if (match_result == FilterMatchResult::kBlockRule && ++ url.path() == "/blocked.png") { ++ tabs_with_blocked_resource_.insert( ++ sessions::SessionTabHelper::IdForTab(wc).id()); ++ } else if (match_result == FilterMatchResult::kAllowRule && ++ url.path() == "/expected.png") { ++ tabs_with_allowed_resource_.insert( ++ sessions::SessionTabHelper::IdForTab(wc).id()); ++ } ++ } ++ ++ void OnPageAllowed(const GURL& url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override {} ++ ++ void OnPopupMatched(const GURL& url, ++ FilterMatchResult match_result, ++ const GURL& opener_url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override {} ++ ++ protected: ++ const int kTabsCount = 4; ++ const char* kTestDomain = "example.com"; ++ std::set tabs_with_blocked_resource_; ++ std::set tabs_with_allowed_resource_; ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockMultipleTabsBrowserTest, PRE_OpenManyTabs) { ++ // Load page in already opened tab ++ ASSERT_TRUE(ui_test_utils::NavigateToURL( ++ browser(), ++ embedded_test_server()->GetURL(kTestDomain, "/tab-restore.html"))); ++ // Open more tabs ++ for (int i = 0; i < kTabsCount - 1; ++i) { ++ ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition( ++ browser(), ++ embedded_test_server()->GetURL(kTestDomain, "/tab-restore.html"), ++ WindowOpenDisposition::NEW_FOREGROUND_TAB, ++ ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)); ++ } ++ EXPECT_EQ(kTabsCount, browser()->tab_strip_model()->count()); ++ EXPECT_EQ(kTabsCount, static_cast(tabs_with_blocked_resource_.size())); ++ EXPECT_EQ(kTabsCount, static_cast(tabs_with_allowed_resource_.size())); ++ ++ // Open a new browser instance ++ ui_test_utils::NavigateToURLWithDisposition( ++ browser(), GURL(url::kAboutBlankURL), WindowOpenDisposition::NEW_WINDOW, ++ ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); ++ BrowserList* active_browser_list = BrowserList::GetInstance(); ++ EXPECT_EQ(2u, active_browser_list->size()); ++ ++ // Close the 1st browser and clear tabs test data ++ CloseBrowserSynchronously(browser()); ++ EXPECT_EQ(1u, active_browser_list->size()); ++ tabs_with_blocked_resource_.clear(); ++ tabs_with_allowed_resource_.clear(); ++ ++ Browser* browser = active_browser_list->get(0); ++ // Restore tabs from1 st browser instance (already closed) in 2nd instance ++ RestoreTabs(browser); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockMultipleTabsBrowserTest, OpenManyTabs) { ++ ASSERT_EQ(0u, tabs_with_blocked_resource_.size()); ++ ASSERT_EQ(0u, tabs_with_allowed_resource_.size()); ++ // Restore tabs from previous session (previous test) ++ RestoreTabs(browser()); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_non_ascii_browsertest.cc b/chrome/browser/adblock/adblock_non_ascii_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_non_ascii_browsertest.cc +@@ -0,0 +1,77 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++namespace adblock { ++ ++class AdblockNonASCIIBrowserTest : public InProcessBrowserTest { ++ public: ++ void SetUpOnMainThread() override { ++ host_resolver()->AddRule("xn----dtbfdbwspgnceulm.xn--p1ai", "127.0.0.1"); ++ embedded_test_server()->ServeFilesFromSourceDirectory( ++ "chrome/test/data/adblock"); ++ content::SetupCrossSiteRedirector(embedded_test_server()); ++ ASSERT_TRUE(embedded_test_server()->Start()); ++ } ++ ++ void SetFilters(std::vector filters) { ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->RemoveCustomFilter(kAllowlistEverythingFilter); ++ for (auto& filter : filters) { ++ controller->AddCustomFilter(filter); ++ } ++ } ++ ++ std::string ExecuteScriptAndExtractString(const std::string& js_code) const { ++ content::WebContents* web_contents = ++ browser()->tab_strip_model()->GetActiveWebContents(); ++ return content::EvalJs(web_contents->GetPrimaryMainFrame(), js_code) ++ .ExtractString(); ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockNonASCIIBrowserTest, BlockNonASCII) { ++ static constexpr char kCheckVisibility[] = ++ R"(getComputedStyle(document.getElementsByClassName("форум")[0]).display)"; ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL( ++ browser(), ++ embedded_test_server()->GetURL("форум-трейдеров.рф", "/non-ascii.html"))); ++ EXPECT_EQ("block", ExecuteScriptAndExtractString(kCheckVisibility)); ++ ++ SetFilters({"xn----dtbfdbwspgnceulm.xn--p1ai##.форум"}); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL( ++ browser(), ++ embedded_test_server()->GetURL("форум-трейдеров.рф", "/non-ascii.html"))); ++ ++ EXPECT_EQ("none", ExecuteScriptAndExtractString(kCheckVisibility)); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_subscription_service_browsertest.cc b/chrome/browser/adblock/adblock_subscription_service_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_subscription_service_browsertest.cc +@@ -0,0 +1,169 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++#include "base/ranges/algorithm.h" ++#include "base/strings/string_split.h" ++#include "base/test/bind.h" ++#include "base/time/time.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/subscription_persistent_metadata_factory.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/subscription/subscription_service.h" ++#include "components/version_info/version_info.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/http/http_request_headers.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++ ++namespace adblock { ++ ++class AdblockSubscriptionServiceBrowserTest ++ : public InProcessBrowserTest, ++ public AdblockController::Observer, ++ public SubscriptionService::SubscriptionObserver { ++ public: ++ AdblockSubscriptionServiceBrowserTest() { ++ SubscriptionServiceFactory::SetUpdateCheckAndDelayIntervalsForTesting( ++ base::Seconds(1), base::Seconds(1)); ++ } ++ void SetUpOnMainThread() override { ++ InProcessBrowserTest::SetUpOnMainThread(); ++ https_server_ = std::make_unique( ++ net::EmbeddedTestServer::TYPE_HTTPS); ++ https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); ++ } ++ ++ bool RequestHeadersContainAcceptLanguage( ++ const net::test_server::HttpRequest& request) { ++ const auto accept_language_it = ++ request.headers.find(net::HttpRequestHeaders::kAcceptLanguage); ++ return accept_language_it != request.headers.end() && ++ !accept_language_it->second.empty(); ++ } ++ ++ bool RequestHeadersContainAcceptEncodingBrotli( ++ const net::test_server::HttpRequest& request) { ++ const auto accept_encoding_it = ++ request.headers.find(net::HttpRequestHeaders::kAcceptEncoding); ++ if (accept_encoding_it == request.headers.end()) ++ return false; ++ const auto split_encodings = ++ base::SplitString(accept_encoding_it->second, ",", ++ base::WhitespaceHandling::TRIM_WHITESPACE, ++ base::SplitResult::SPLIT_WANT_NONEMPTY); ++ return base::ranges::find(split_encodings, "br") != split_encodings.end(); ++ } ++ ++ std::unique_ptr ++ HandleSubscriptionUpdateRequestWithUrlCheck( ++ std::string expected_url_part, ++ const net::test_server::HttpRequest& request) { ++ static const char kSubscriptionHeader[] = ++ "[Adblock Plus 2.0]\n" ++ "! Checksum: X5A8vtJDBW2a9EgS9glqbg\n" ++ "! Version: 202202061935\n" ++ "! Last modified: 06 Feb 2022 19:35 UTC\n" ++ "! Expires: 1 days (update frequency)\n\n"; ++ if (base::StartsWith(request.relative_url, kSubscription, ++ base::CompareCase::SENSITIVE)) { ++ EXPECT_TRUE(RequestHeadersContainAcceptLanguage(request)); ++ EXPECT_TRUE(RequestHeadersContainAcceptEncodingBrotli(request)); ++ std::string os; ++ base::ReplaceChars(version_info::GetOSType(), base::kWhitespaceASCII, "", ++ &os); ++ EXPECT_TRUE(request.relative_url.find(expected_url_part) != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("addonName=eyeo-chromium-sdk") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("addonVersion=1.0") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("platformVersion=1.0") != ++ std::string::npos); ++ EXPECT_TRUE(request.relative_url.find("platform=" + os) != ++ std::string::npos); ++ auto http_response = ++ std::make_unique(); ++ http_response->set_code(net::HTTP_OK); ++ http_response->set_content(kSubscriptionHeader); ++ http_response->set_content_type("text/plain"); ++ return std::move(http_response); ++ } ++ ++ // Unhandled requests result in the Embedded test server sending a 404. ++ return nullptr; ++ } ++ ++ void ExpectFilterListRequestMadeWithLastVersion(std::string last_version) { ++ https_server_->RegisterRequestHandler( ++ base::BindRepeating(&AdblockSubscriptionServiceBrowserTest:: ++ HandleSubscriptionUpdateRequestWithUrlCheck, ++ base::Unretained(this), last_version)); ++ ASSERT_TRUE(https_server_->Start(kPort)); ++ } ++ ++ // adblock::AdblockController::Observer: ++ void OnSubscriptionUpdated(const GURL& url) override { ++ if (base::StartsWith(url.spec(), ++ https_server_->GetURL(kSubscription).spec())) { ++ // In order to ensure next run requests an update, mark the subscription ++ // as almost expired. ++ SubscriptionPersistentMetadataFactory::GetForBrowserContext( ++ browser()->profile()) ++ ->SetExpirationInterval(url, base::Milliseconds(1)); ++ CloseBrowserAsynchronously(browser()); ++ } ++ } ++ ++ std::unique_ptr https_server_; ++ static const std::string kSubscription; ++ // Port is hardcoded so the server url is the same across tests ++ static const int kPort = 65432; ++}; ++ ++const std::string AdblockSubscriptionServiceBrowserTest::kSubscription = ++ "/subscription.txt"; ++ ++IN_PROC_BROWSER_TEST_F(AdblockSubscriptionServiceBrowserTest, PRE_LastVersion) { ++ ExpectFilterListRequestMadeWithLastVersion("&lastVersion=0&"); ++ // Downloading a filter list and setting its expiry time to almost zero, so ++ // the next run will have to update it ASAP. ++ ++ // Using a custom subscription URL here because before test sets ++ // up the server then SubscriptionService already started fetching default ++ // subscriptions. ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->AddObserver(this); ++ controller->InstallSubscription(https_server_->GetURL(kSubscription)); ++ // Wait until subscription is downloaded and stored. ++ RunUntilBrowserProcessQuits(); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockSubscriptionServiceBrowserTest, LastVersion) { ++ ExpectFilterListRequestMadeWithLastVersion("&lastVersion=202202061935&"); ++ auto* controller = ++ AdblockControllerFactory::GetForBrowserContext(browser()->profile()); ++ controller->AddObserver(this); ++ // Wait for subscription update to trigger a network request. ++ RunUntilBrowserProcessQuits(); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_telemetry_service_browsertest.cc b/chrome/browser/adblock/adblock_telemetry_service_browsertest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_telemetry_service_browsertest.cc +@@ -0,0 +1,255 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++#include "base/json/json_reader.h" ++#include "chrome/browser/adblock/adblock_telemetry_service_factory.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/test/base/in_process_browser_test.h" ++#include "components/adblock/core/activeping_telemetry_topic_provider.h" ++#include "content/public/browser/browser_task_traits.h" ++#include "content/public/test/browser_test.h" ++#include "content/public/test/browser_test_utils.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++ ++namespace adblock { ++ ++class AdblockTelemetryServiceBrowserTestBase : public InProcessBrowserTest { ++ public: ++ // We need to set server and request handler asap ++ void SetUpInProcessBrowserTestFixture() override { ++ InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); ++ host_resolver()->AddRule( ++ ActivepingTelemetryTopicProvider::DefaultBaseUrl().host(), "127.0.0.1"); ++ http_server_.RegisterRequestHandler(base::BindRepeating( ++ &AdblockTelemetryServiceBrowserTestBase::RequestHandler, ++ base::Unretained(this))); ++ ASSERT_TRUE(http_server_.Start()); ++ ActivepingTelemetryTopicProvider::SetHttpPortForTesting( ++ http_server_.port()); ++ auto testing_interval = base::Seconds(2); ++ ActivepingTelemetryTopicProvider::SetIntervalsForTesting(testing_interval); ++ AdblockTelemetryServiceFactory::GetInstance() ++ ->SetCheckAndDelayIntervalsForTesting(testing_interval, ++ testing_interval); ++ } ++ ++ base::Value* GetFirstPing(absl::optional& parsed) { ++ return GetPayload(parsed)->Find("first_ping"); ++ } ++ ++ base::Value* GetLastPing(absl::optional& parsed) { ++ return GetPayload(parsed)->Find("last_ping"); ++ } ++ ++ base::Value* GetLastPingTag(absl::optional& parsed) { ++ return GetPayload(parsed)->Find("last_ping_tag"); ++ } ++ ++ base::Value* GetPreviousLastPing(absl::optional& parsed) { ++ return GetPayload(parsed)->Find("previous_last_ping"); ++ } ++ ++ void CloseBrowserFromAnyThread() { ++ content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING}) ++ ->PostTask(FROM_HERE, ++ base::BindOnce(&AdblockTelemetryServiceBrowserTestBase:: ++ CloseBrowserAsynchronously, ++ base::Unretained(this), browser())); ++ } ++ ++ std::unique_ptr CreateResponse( ++ const std::string& token) { ++ auto http_response = ++ std::make_unique(); ++ http_response->set_code(net::HTTP_OK); ++ http_response->set_content("{\"token\": \"" + token + "\"}"); ++ http_response->set_content_type("text/plain"); ++ return std::move(http_response); ++ } ++ ++ virtual std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) = 0; ++ ++ private: ++ base::Value::Dict* GetPayload(absl::optional& parsed) { ++ EXPECT_TRUE(parsed && parsed->is_dict()); ++ base::Value::Dict* parsed_dict = parsed->GetIfDict(); ++ EXPECT_TRUE(parsed_dict); ++ base::Value::Dict* payload = parsed_dict->FindDict("payload"); ++ EXPECT_TRUE(payload); ++ return payload; ++ } ++ ++ net::EmbeddedTestServer http_server_; ++}; ++ ++// Test three initial pings each after startup and each fails for the 1st time ++class AdblockTelemetryServiceFirstPingAfterRestartWithRetryBrowserTest ++ : public AdblockTelemetryServiceBrowserTestBase { ++ public: ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) override { ++ EXPECT_TRUE(base::StartsWith(request.relative_url, ++ "/topic/eyeochromium_activeping/version/1")); ++ EXPECT_TRUE(request.has_content); ++ absl::optional parsed = ++ base::JSONReader::Read(request.content); ++ base::Value* first_ping = GetFirstPing(parsed); ++ base::Value* last_ping = GetLastPing(parsed); ++ base::Value* previous_last_ping = GetPreviousLastPing(parsed); ++ ++ if (expected_first_ping_.empty()) { ++ EXPECT_FALSE(first_ping); ++ } else { ++ EXPECT_EQ(expected_first_ping_, *first_ping); ++ } ++ ++ if (expected_last_ping_.empty()) { ++ EXPECT_FALSE(last_ping); ++ } else { ++ EXPECT_EQ(expected_last_ping_, *last_ping); ++ } ++ ++ if (expected_previous_last_ping_.empty()) { ++ EXPECT_FALSE(previous_last_ping); ++ } else { ++ EXPECT_EQ(expected_previous_last_ping_, *previous_last_ping); ++ } ++ ++ if (!attempt_++) { ++ // Force retry by 404 response but 1st save last_ping_tag if any ++ base::Value* last_ping_tag = GetLastPingTag(parsed); ++ if (last_ping_tag) { ++ previous_last_ping_tag_ = last_ping_tag->GetString(); ++ } ++ return nullptr; ++ } ++ ++ // Verifies that retried ping has the same last_ping_tag ++ if (!previous_last_ping_tag_.empty()) { ++ base::Value* last_ping_tag = GetLastPingTag(parsed); ++ EXPECT_EQ(previous_last_ping_tag_, *last_ping_tag); ++ } ++ ++ // If we get expected telemetry ping with retry we simply finish the test ++ // by closing the browser, otherwise test will fail with a timeout. ++ CloseBrowserFromAnyThread(); ++ ++ // This will be still processed before CloseBrowserFromAnyThread() applies ++ return CreateResponse(server_response_); ++ } ++ ++ void TearDownInProcessBrowserTestFixture() override { ++ // Make sure we called RequestHandler exactly twice: 1st ping failed, 2nd ++ // was successful ++ EXPECT_EQ(2, attempt_); ++ } ++ ++ protected: ++ std::string server_response_; ++ std::string expected_first_ping_; ++ std::string expected_last_ping_; ++ std::string expected_previous_last_ping_; ++ ++ private: ++ int attempt_ = 0; ++ std::string previous_last_ping_tag_ = ""; ++}; ++ ++IN_PROC_BROWSER_TEST_F( ++ AdblockTelemetryServiceFirstPingAfterRestartWithRetryBrowserTest, ++ PRE_PRE_TestPing) { ++ // Sets the ping to be returned by the server and checked in the next test ++ server_response_ = "11111"; ++ RunUntilBrowserProcessQuits(); ++} ++ ++IN_PROC_BROWSER_TEST_F( ++ AdblockTelemetryServiceFirstPingAfterRestartWithRetryBrowserTest, ++ PRE_TestPing) { ++ // Sets the ping to be returned by the server and checked in the next test ++ server_response_ = "22222"; ++ expected_first_ping_ = expected_last_ping_ = "11111"; ++ RunUntilBrowserProcessQuits(); ++} ++ ++IN_PROC_BROWSER_TEST_F( ++ AdblockTelemetryServiceFirstPingAfterRestartWithRetryBrowserTest, ++ TestPing) { ++ expected_first_ping_ = "11111"; ++ expected_last_ping_ = "22222"; ++ expected_previous_last_ping_ = "11111"; ++ RunUntilBrowserProcessQuits(); ++} ++ ++// Test three inital pings ++class AdblockTelemetryServiceSubsequentPingsBrowserTest ++ : public AdblockTelemetryServiceBrowserTestBase { ++ public: ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) override { ++ EXPECT_TRUE(base::StartsWith(request.relative_url, ++ "/topic/eyeochromium_activeping/version/1")); ++ EXPECT_TRUE(request.has_content); ++ absl::optional parsed = ++ base::JSONReader::Read(request.content); ++ base::Value* first_ping = GetFirstPing(parsed); ++ base::Value* last_ping = GetLastPing(parsed); ++ base::Value* previous_last_ping = GetPreviousLastPing(parsed); ++ ++ if (count_ == 1) { ++ // No ping payload in the very 1st ping ++ EXPECT_FALSE(first_ping); ++ EXPECT_FALSE(last_ping); ++ } else if (count_ == 2) { ++ // For 2nd ping `first_ping` == `last_ping` ++ EXPECT_EQ(first_ping_, *first_ping); ++ EXPECT_EQ(first_ping_, *last_ping); ++ } else if (count_ == 3) { ++ // From 3rd ping onward `first_ping` != `last_ping` and we also get ++ // `previous_last_ping` ++ EXPECT_EQ(first_ping_, *first_ping); ++ EXPECT_EQ(second_ping_, *last_ping); ++ EXPECT_EQ(first_ping_, *previous_last_ping); ++ } ++ ++ // If we get three expected telemetry pings we simply finish the test by ++ // closing the browser, otherwise test will fail with a timeout. ++ if (count_ == 3) { ++ CloseBrowserFromAnyThread(); ++ return nullptr; ++ } ++ return CreateResponse(count_++ == 1 ? first_ping_ : second_ping_); ++ } ++ ++ void TearDownInProcessBrowserTestFixture() override { ++ // Make sure we called RequestHandler exactly three times ++ EXPECT_EQ(3, count_); ++ } ++ ++ private: ++ const std::string first_ping_ = "11111"; ++ const std::string second_ping_ = "22222"; ++ int count_ = 1; ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockTelemetryServiceSubsequentPingsBrowserTest, ++ TestPing) { ++ RunUntilBrowserProcessQuits(); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_telemetry_service_factory.cc b/chrome/browser/adblock/adblock_telemetry_service_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_telemetry_service_factory.cc +@@ -0,0 +1,120 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/adblock_telemetry_service_factory.h" ++ ++#include ++ ++#include "base/no_destructor.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/common/pref_names.h" ++#include "components/adblock/core/activeping_telemetry_topic_provider.h" ++#include "components/adblock/core/adblock_telemetry_service.h" ++#include "components/adblock/core/common/adblock_utils.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/storage_partition.h" ++ ++namespace adblock { ++namespace { ++std::optional g_check_interval_for_testing; ++std::optional g_initial_delay_for_testing; ++ ++base::TimeDelta GetInitialDelay() { ++ static base::TimeDelta kInitialDelay = ++ g_initial_delay_for_testing ? g_initial_delay_for_testing.value() ++ : base::Seconds(30); ++ return kInitialDelay; ++} ++ ++base::TimeDelta GetCheckInterval() { ++ static base::TimeDelta kCheckInterval = ++ g_check_interval_for_testing ? g_check_interval_for_testing.value() ++ : base::Minutes(5); ++ return kCheckInterval; ++} ++} // namespace ++ ++// static ++AdblockTelemetryService* AdblockTelemetryServiceFactory::GetForProfile( ++ Profile* profile) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(profile, true)); ++} ++// static ++AdblockTelemetryServiceFactory* AdblockTelemetryServiceFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++AdblockTelemetryServiceFactory::AdblockTelemetryServiceFactory() ++ : BrowserContextKeyedServiceFactory( ++ "AdblockTelemetryService", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(AdblockControllerFactory::GetInstance()); ++} ++ ++AdblockTelemetryServiceFactory::~AdblockTelemetryServiceFactory() = default; ++ ++KeyedService* AdblockTelemetryServiceFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ // Need to use a URLLoaderFactory specific to the browser context, not from ++ // system_network_context_manager(), because the required Accept-Language ++ // header depends on user's language settings and is not present in requests ++ // made from the System network context. ++ scoped_refptr url_loader_factory = ++ context->GetDefaultStoragePartition() ++ ->GetURLLoaderFactoryForBrowserProcess(); ++ auto* prefs = Profile::FromBrowserContext(context)->GetPrefs(); ++ auto service = std::make_unique( ++ AdblockControllerFactory::GetForBrowserContext(context), ++ url_loader_factory, GetInitialDelay(), GetCheckInterval()); ++ service->AddTopicProvider(std::make_unique( ++ utils::GetAppInfo(), prefs, ++ AdblockControllerFactory::GetForBrowserContext(context), ++ ActivepingTelemetryTopicProvider::DefaultBaseUrl(), ++ ActivepingTelemetryTopicProvider::DefaultAuthToken())); ++ ++ if (url_loader_factory) ++ service->Start(); ++ ++ return service.release(); ++} ++ ++content::BrowserContext* AdblockTelemetryServiceFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++bool AdblockTelemetryServiceFactory::ServiceIsNULLWhileTesting() const { ++ return true; ++} ++ ++bool AdblockTelemetryServiceFactory::ServiceIsCreatedWithBrowserContext() ++ const { ++ return true; ++} ++ ++void AdblockTelemetryServiceFactory::SetCheckAndDelayIntervalsForTesting( ++ base::TimeDelta check_interval, ++ base::TimeDelta initial_delay) { ++ g_check_interval_for_testing = check_interval; ++ g_initial_delay_for_testing = initial_delay; ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/adblock_telemetry_service_factory.h b/chrome/browser/adblock/adblock_telemetry_service_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/adblock_telemetry_service_factory.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_ADBLOCK_TELEMETRY_SERVICE_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_ADBLOCK_TELEMETRY_SERVICE_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "base/time/time.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++ ++class Profile; ++ ++namespace adblock { ++class AdblockTelemetryService; ++class AdblockTelemetryServiceFactory ++ : public BrowserContextKeyedServiceFactory { ++ public: ++ static AdblockTelemetryService* GetForProfile(Profile* profile); ++ static AdblockTelemetryServiceFactory* GetInstance(); ++ ++ // Sets the initial delay and interval checks required for browser tests. ++ // Must be called before BuildServiceInstanceFor(). ++ void SetCheckAndDelayIntervalsForTesting(base::TimeDelta check_interval, ++ base::TimeDelta initial_delay); ++ ++ private: ++ friend class base::NoDestructor; ++ AdblockTelemetryServiceFactory(); ++ ~AdblockTelemetryServiceFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++ bool ServiceIsNULLWhileTesting() const override; ++ bool ServiceIsCreatedWithBrowserContext() const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_ADBLOCK_TELEMETRY_SERVICE_FACTORY_H_ +diff --git a/chrome/browser/adblock/content_security_policy_injector_factory.cc b/chrome/browser/adblock/content_security_policy_injector_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/content_security_policy_injector_factory.cc +@@ -0,0 +1,69 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/content_security_policy_injector_factory.h" ++ ++#include ++ ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/content/browser/content_security_policy_injector_impl.h" ++#include "components/adblock/content/browser/frame_hierarchy_builder.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++ContentSecurityPolicyInjector* ++ContentSecurityPolicyInjectorFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++ContentSecurityPolicyInjectorFactory* ++ContentSecurityPolicyInjectorFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++ContentSecurityPolicyInjectorFactory::ContentSecurityPolicyInjectorFactory() ++ : BrowserContextKeyedServiceFactory( ++ "ContentSecurityPolicyInjector", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(SubscriptionServiceFactory::GetInstance()); ++} ++ ++ContentSecurityPolicyInjectorFactory::~ContentSecurityPolicyInjectorFactory() = ++ default; ++ ++KeyedService* ContentSecurityPolicyInjectorFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new ContentSecurityPolicyInjectorImpl( ++ SubscriptionServiceFactory::GetForBrowserContext(context), ++ std::make_unique()); ++} ++ ++content::BrowserContext* ++ContentSecurityPolicyInjectorFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/content_security_policy_injector_factory.h b/chrome/browser/adblock/content_security_policy_injector_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/content_security_policy_injector_factory.h +@@ -0,0 +1,49 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_CONTENT_SECURITY_POLICY_INJECTOR_H_ ++#define CHROME_BROWSER_ADBLOCK_CONTENT_SECURITY_POLICY_INJECTOR_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class ContentSecurityPolicyInjector; ++class ContentSecurityPolicyInjectorFactory ++ : public BrowserContextKeyedServiceFactory { ++ public: ++ static ContentSecurityPolicyInjector* GetForBrowserContext( ++ content::BrowserContext* context); ++ static ContentSecurityPolicyInjectorFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ ContentSecurityPolicyInjectorFactory(); ++ ~ContentSecurityPolicyInjectorFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_CONTENT_SECURITY_POLICY_INJECTOR_H_ +diff --git a/chrome/browser/adblock/element_hider_factory.cc b/chrome/browser/adblock/element_hider_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/element_hider_factory.cc +@@ -0,0 +1,63 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/element_hider_factory.h" ++ ++#include ++ ++#include "chrome/browser/adblock/subscription_service_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/content/browser/element_hider_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++ElementHider* ElementHiderFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++ElementHiderFactory* ElementHiderFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++ElementHiderFactory::ElementHiderFactory() ++ : BrowserContextKeyedServiceFactory( ++ "ElementHider", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(adblock::SubscriptionServiceFactory::GetInstance()); ++} ++ ++ElementHiderFactory::~ElementHiderFactory() = default; ++ ++KeyedService* ElementHiderFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new ElementHiderImpl( ++ adblock::SubscriptionServiceFactory::GetForBrowserContext(context)); ++} ++ ++content::BrowserContext* ElementHiderFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/element_hider_factory.h b/chrome/browser/adblock/element_hider_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/element_hider_factory.h +@@ -0,0 +1,47 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_ELEMENT_HIDER_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_ELEMENT_HIDER_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class ElementHider; ++class ElementHiderFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ static ElementHider* GetForBrowserContext(content::BrowserContext* context); ++ static ElementHiderFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ ElementHiderFactory(); ++ ~ElementHiderFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_ELEMENT_HIDER_FACTORY_H_ +diff --git a/chrome/browser/adblock/resource_classification_runner_factory.cc b/chrome/browser/adblock/resource_classification_runner_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/resource_classification_runner_factory.cc +@@ -0,0 +1,71 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++ ++#include ++ ++#include "chrome/browser/adblock/sitekey_storage_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/content/browser/frame_hierarchy_builder.h" ++#include "components/adblock/content/browser/resource_classification_runner_impl.h" ++#include "components/adblock/core/classifier/resource_classifier_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++ResourceClassificationRunner* ++ResourceClassificationRunnerFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++ResourceClassificationRunnerFactory* ++ResourceClassificationRunnerFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++ResourceClassificationRunnerFactory::ResourceClassificationRunnerFactory() ++ : BrowserContextKeyedServiceFactory( ++ "ResourceClassificationRunner", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(SitekeyStorageFactory::GetInstance()); ++} ++ ++ResourceClassificationRunnerFactory::~ResourceClassificationRunnerFactory() = ++ default; ++ ++KeyedService* ResourceClassificationRunnerFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new ResourceClassificationRunnerImpl( ++ base::MakeRefCounted(), ++ std::make_unique(), ++ SitekeyStorageFactory::GetForBrowserContext(context)); ++} ++ ++content::BrowserContext* ++ResourceClassificationRunnerFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/resource_classification_runner_factory.h b/chrome/browser/adblock/resource_classification_runner_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/resource_classification_runner_factory.h +@@ -0,0 +1,49 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_RESOURCE_CLASSIFICATION_RUNNER_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_RESOURCE_CLASSIFICATION_RUNNER_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class ResourceClassificationRunner; ++class ResourceClassificationRunnerFactory ++ : public BrowserContextKeyedServiceFactory { ++ public: ++ static ResourceClassificationRunner* GetForBrowserContext( ++ content::BrowserContext* context); ++ static ResourceClassificationRunnerFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ ResourceClassificationRunnerFactory(); ++ ~ResourceClassificationRunnerFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_RESOURCE_CLASSIFICATION_RUNNER_FACTORY_H_ +diff --git a/chrome/browser/adblock/session_stats_factory.cc b/chrome/browser/adblock/session_stats_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/session_stats_factory.cc +@@ -0,0 +1,64 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/session_stats_factory.h" ++ ++#include ++ ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/content/browser/session_stats_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++SessionStats* SessionStatsFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++ ++// static ++SessionStatsFactory* SessionStatsFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++SessionStatsFactory::SessionStatsFactory() ++ : BrowserContextKeyedServiceFactory( ++ "SessionStats", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(ResourceClassificationRunnerFactory::GetInstance()); ++} ++ ++SessionStatsFactory::~SessionStatsFactory() = default; ++ ++KeyedService* SessionStatsFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new SessionStatsImpl( ++ ResourceClassificationRunnerFactory::GetForBrowserContext(context)); ++} ++ ++content::BrowserContext* SessionStatsFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/session_stats_factory.h b/chrome/browser/adblock/session_stats_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/session_stats_factory.h +@@ -0,0 +1,47 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_SESSION_STATS_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_SESSION_STATS_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class SessionStats; ++class SessionStatsFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ static SessionStats* GetForBrowserContext(content::BrowserContext* context); ++ static SessionStatsFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ SessionStatsFactory(); ++ ~SessionStatsFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_SESSION_STATS_FACTORY_H_ +diff --git a/chrome/browser/adblock/sitekey_storage_factory.cc b/chrome/browser/adblock/sitekey_storage_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/sitekey_storage_factory.cc +@@ -0,0 +1,59 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/sitekey_storage_factory.h" ++ ++#include ++ ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/core/sitekey_storage_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++SitekeyStorage* SitekeyStorageFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++SitekeyStorageFactory* SitekeyStorageFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++SitekeyStorageFactory::SitekeyStorageFactory() ++ : BrowserContextKeyedServiceFactory( ++ "SitekeyStorage", ++ BrowserContextDependencyManager::GetInstance()) {} ++ ++SitekeyStorageFactory::~SitekeyStorageFactory() = default; ++ ++KeyedService* SitekeyStorageFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new SitekeyStorageImpl(); ++} ++ ++content::BrowserContext* SitekeyStorageFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/sitekey_storage_factory.h b/chrome/browser/adblock/sitekey_storage_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/sitekey_storage_factory.h +@@ -0,0 +1,47 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_SITEKEY_STORAGE_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_SITEKEY_STORAGE_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class SitekeyStorage; ++class SitekeyStorageFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ static SitekeyStorage* GetForBrowserContext(content::BrowserContext* context); ++ static SitekeyStorageFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ SitekeyStorageFactory(); ++ ~SitekeyStorageFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_SITEKEY_STORAGE_FACTORY_H_ +diff --git a/chrome/browser/adblock/subscription_persistent_metadata_factory.cc b/chrome/browser/adblock/subscription_persistent_metadata_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/subscription_persistent_metadata_factory.cc +@@ -0,0 +1,63 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/subscription_persistent_metadata_factory.h" ++ ++#include ++ ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/core/subscription/subscription_persistent_metadata_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++SubscriptionPersistentMetadata* ++SubscriptionPersistentMetadataFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++SubscriptionPersistentMetadataFactory* ++SubscriptionPersistentMetadataFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++SubscriptionPersistentMetadataFactory::SubscriptionPersistentMetadataFactory() ++ : BrowserContextKeyedServiceFactory( ++ "AdblockSubscriptionPersistentMetadata", ++ BrowserContextDependencyManager::GetInstance()) {} ++SubscriptionPersistentMetadataFactory:: ++ ~SubscriptionPersistentMetadataFactory() = default; ++ ++KeyedService* SubscriptionPersistentMetadataFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new SubscriptionPersistentMetadataImpl( ++ Profile::FromBrowserContext(context)->GetPrefs()); ++} ++ ++content::BrowserContext* ++SubscriptionPersistentMetadataFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/subscription_persistent_metadata_factory.h b/chrome/browser/adblock/subscription_persistent_metadata_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/subscription_persistent_metadata_factory.h +@@ -0,0 +1,49 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_PERSISTENT_METADATA_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_PERSISTENT_METADATA_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class SubscriptionPersistentMetadata; ++class SubscriptionPersistentMetadataFactory ++ : public BrowserContextKeyedServiceFactory { ++ public: ++ static SubscriptionPersistentMetadata* GetForBrowserContext( ++ content::BrowserContext* context); ++ static SubscriptionPersistentMetadataFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ SubscriptionPersistentMetadataFactory(); ++ ~SubscriptionPersistentMetadataFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_PERSISTENT_METADATA_FACTORY_H_ +diff --git a/chrome/browser/adblock/subscription_service_factory.cc b/chrome/browser/adblock/subscription_service_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/subscription_service_factory.cc +@@ -0,0 +1,185 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/adblock/subscription_service_factory.h" ++ ++#include ++#include ++#include ++ ++#include "base/bind.h" ++#include "base/threading/sequenced_task_runner_handle.h" ++#include "base/trace_event/trace_event.h" ++#include "chrome/browser/adblock/subscription_persistent_metadata_factory.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "components/adblock/core/configuration/persistent_filtering_configuration.h" ++#include "components/adblock/core/converter/converter.h" ++#include "components/adblock/core/subscription/installed_subscription_impl.h" ++#include "components/adblock/core/subscription/ongoing_subscription_request_impl.h" ++#include "components/adblock/core/subscription/preloaded_subscription_provider_impl.h" ++#include "components/adblock/core/subscription/subscription_config.h" ++#include "components/adblock/core/subscription/subscription_downloader_impl.h" ++#include "components/adblock/core/subscription/subscription_persistent_storage_impl.h" ++#include "components/adblock/core/subscription/subscription_service_impl.h" ++#include "components/adblock/core/subscription/subscription_updater.h" ++#include "components/adblock/core/subscription/subscription_updater_impl.h" ++#include "components/adblock/core/subscription/subscription_validator_impl.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "components/pref_registry/pref_registry_syncable.h" ++#include "components/prefs/pref_service.h" ++#include "content/public/browser/browser_context.h" ++#include "content/public/browser/storage_partition.h" ++ ++namespace adblock { ++namespace { ++ ++std::optional g_update_check_interval_for_testing; ++std::optional g_update_initial_delay_for_testing; ++ ++base::TimeDelta GetUpdateInitialDelay() { ++ static base::TimeDelta kInitialDelay = ++ g_update_initial_delay_for_testing ++ ? g_update_initial_delay_for_testing.value() ++ : base::Seconds(30); ++ return kInitialDelay; ++} ++ ++base::TimeDelta GetUpdateCheckInterval() { ++ static base::TimeDelta kCheckInterval = ++ g_update_check_interval_for_testing ++ ? g_update_check_interval_for_testing.value() ++ : base::Hours(1); ++ return kCheckInterval; ++} ++ ++constexpr net::BackoffEntry::Policy kRetryBackoffPolicy = { ++ 0, // Number of initial errors to ignore. ++ 5000, // Initial delay in ms. ++ 2.0, // Factor by which the waiting time will be multiplied. ++ 0.2, // Fuzzing percentage. ++ 60 * 60 * 1000, // Maximum delay in ms. ++ -1, // Never discard the entry. ++ false, // Use initial delay. ++}; ++ ++std::unique_ptr MakeOngoingSubscriptionRequest( ++ PrefService* prefs, ++ scoped_refptr url_loader_factory) { ++ return std::make_unique( ++ prefs, &kRetryBackoffPolicy, url_loader_factory); ++} ++ ++ConverterResult ConvertFileToFlatbuffer(const GURL& subscription_url, ++ const base::FilePath& path) { ++ TRACE_EVENT1("eyeo", "ConvertFileToFlatbuffer", "url", ++ subscription_url.spec()); ++ std::ifstream input_stream(path.AsUTF8Unsafe()); ++ if (!input_stream.is_open() || !input_stream.good()) { ++ ConverterResult result; ++ result.status = ConverterResult::Error; ++ return result; ++ } ++ return Converter().Convert( ++ input_stream, ++ {subscription_url, config::AllowPrivilegedFilters(subscription_url)}); ++} ++ ++scoped_refptr CustomFilterConverter( ++ const std::vector& filters) { ++ auto raw_data = Converter().Convert(filters, {CustomFiltersUrl(), true}); ++ return base::MakeRefCounted( ++ std::move(raw_data), Subscription::InstallationState::Installed, ++ base::Time()); ++} ++ ++std::unique_ptr MakeSubscriptionUpdater() { ++ return std::make_unique(GetUpdateInitialDelay(), ++ GetUpdateCheckInterval()); ++} ++ ++} // namespace ++ ++// static ++SubscriptionService* SubscriptionServiceFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++SubscriptionServiceFactory* SubscriptionServiceFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++SubscriptionServiceFactory::SubscriptionServiceFactory() ++ : BrowserContextKeyedServiceFactory( ++ "AdblockSubscriptionService", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(SubscriptionPersistentMetadataFactory::GetInstance()); ++} ++SubscriptionServiceFactory::~SubscriptionServiceFactory() = default; ++ ++KeyedService* SubscriptionServiceFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ auto* prefs = Profile::FromBrowserContext(context)->GetPrefs(); ++ auto main_thread_task_runner = base::SequencedTaskRunnerHandle::Get(); ++ auto* persistent_metadata = ++ SubscriptionPersistentMetadataFactory::GetForBrowserContext(context); ++ scoped_refptr url_loader_factory = ++ context->GetDefaultStoragePartition() ++ ->GetURLLoaderFactoryForBrowserProcess(); ++ ++ auto storage = std::make_unique( ++ context->GetPath().AppendASCII("adblock_subscriptions"), ++ base::MakeRefCounted( ++ prefs, CurrentSchemaVersion(), main_thread_task_runner), ++ persistent_metadata); ++ auto downloader = std::make_unique( ++ utils::GetAppInfo(), ++ base::BindRepeating(&MakeOngoingSubscriptionRequest, ++ Profile::FromBrowserContext(context)->GetPrefs(), ++ url_loader_factory), ++ base::BindRepeating(&ConvertFileToFlatbuffer), persistent_metadata); ++ ++ return new SubscriptionServiceImpl( ++ std::move(storage), std::move(downloader), ++ std::make_unique(prefs), ++ MakeSubscriptionUpdater(), base::BindRepeating(&CustomFilterConverter), ++ persistent_metadata); ++} ++ ++content::BrowserContext* SubscriptionServiceFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++void SubscriptionServiceFactory::RegisterProfilePrefs( ++ user_prefs::PrefRegistrySyncable* registry) { ++ adblock::PersistentFilteringConfiguration::RegisterProfilePrefs(registry); ++} ++ ++// static ++void SubscriptionServiceFactory::SetUpdateCheckAndDelayIntervalsForTesting( ++ base::TimeDelta check_interval, ++ base::TimeDelta initial_delay) { ++ g_update_check_interval_for_testing = check_interval; ++ g_update_initial_delay_for_testing = initial_delay; ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/adblock/subscription_service_factory.h b/chrome/browser/adblock/subscription_service_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/adblock/subscription_service_factory.h +@@ -0,0 +1,53 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_SERVICE_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_SERVICE_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class SubscriptionService; ++class SubscriptionServiceFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ static SubscriptionService* GetForBrowserContext( ++ content::BrowserContext* context); ++ static SubscriptionServiceFactory* GetInstance(); ++ static void SetUpdateCheckAndDelayIntervalsForTesting( ++ base::TimeDelta check_interval, ++ base::TimeDelta initial_delay); ++ ++ private: ++ friend class base::NoDestructor; ++ SubscriptionServiceFactory(); ++ ~SubscriptionServiceFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++ void RegisterProfilePrefs( ++ user_prefs::PrefRegistrySyncable* registry) override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_SUBSCRIPTION_SERVICE_FACTORY_H_ +diff --git a/chrome/browser/android/adblock/adblock_jni.cc b/chrome/browser/android/adblock/adblock_jni.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/android/adblock/adblock_jni.cc +@@ -0,0 +1,602 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++#include "chrome/browser/android/adblock/adblock_jni.h" ++ ++#include ++#include ++#include ++ ++#include "base/android/jni_android.h" ++#include "base/android/jni_array.h" ++#include "base/android/jni_string.h" ++#include "base/android/jni_weak_ref.h" ++#include "base/command_line.h" ++#include "base/logging.h" ++#include "base/version.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/android/adblock/adblock_jni_factory.h" ++#include "chrome/browser/android/tab_android.h" ++#include "chrome/browser/browser_process.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "components/adblock/android/jni_headers/AdblockComposeFilterSuggestionsCallback_jni.h" ++#include "components/adblock/android/jni_headers/AdblockController_jni.h" ++#include "components/adblock/android/jni_headers/AdblockElement_jni.h" ++#include "components/adblock/core/adblock_switches.h" ++#include "components/adblock/core/common/adblock_utils.h" ++#include "components/prefs/pref_service.h" ++#include "content/public/browser/browser_thread.h" ++#include "content/public/browser/render_frame_host.h" ++#include "content/public/browser/render_process_host.h" ++#include "content/public/browser/web_contents.h" ++ ++using base::android::AttachCurrentThread; ++using base::android::CheckException; ++using base::android::ConvertJavaStringToUTF8; ++using base::android::ConvertUTF8ToJavaString; ++using base::android::GetClass; ++using base::android::JavaParamRef; ++using base::android::JavaRef; ++using base::android::MethodID; ++using base::android::ScopedJavaGlobalRef; ++using base::android::ScopedJavaLocalRef; ++using base::android::ToJavaArrayOfObjects; ++using base::android::ToJavaArrayOfStrings; ++ ++namespace adblock { ++ ++namespace { ++ ++AdblockController* GetController() { ++ if (!g_browser_process || !g_browser_process->profile_manager()) ++ return nullptr; ++ return AdblockControllerFactory::GetForBrowserContext( ++ g_browser_process->profile_manager()->GetLastUsedProfile()); ++} ++ ++AdblockJNI* GetJNI() { ++ if (!g_browser_process || !g_browser_process->profile_manager()) ++ return nullptr; ++ return AdblockJNIFactory::GetForBrowserContext( ++ g_browser_process->profile_manager()->GetLastUsedProfile()); ++} ++ ++// TODO(mpawlowski): this is currently useless, see DPD-699 ++class JavaElement { ++ public: ++ JavaElement(JNIEnv* environment, const ScopedJavaGlobalRef& object) ++ : obj_(object) {} ++ ++ ~JavaElement() {} ++ ++ std::string GetLocalName() const { ++ JNIEnv* env = AttachCurrentThread(); ++ auto name = Java_AdblockElement_getLocalName(env, obj_); ++ return name.is_null() ? "" : ConvertJavaStringToUTF8(name); ++ } ++ ++ std::string GetDocumentLocation() const { ++ JNIEnv* env = AttachCurrentThread(); ++ auto location = Java_AdblockElement_getDocumentLocation(env, obj_); ++ return location.is_null() ? "" : ConvertJavaStringToUTF8(location); ++ } ++ ++ std::string GetAttribute(const std::string& name) const { ++ JNIEnv* env = AttachCurrentThread(); ++ auto attr = Java_AdblockElement_getAttribute( ++ env, obj_, ConvertUTF8ToJavaString(env, name)); ++ ++ return attr.is_null() ? "" : ConvertJavaStringToUTF8(attr); ++ } ++ ++ std::vector GetChildren() const { ++ std::vector res; ++ ++ if (children_.empty()) { ++ JNIEnv* env = AttachCurrentThread(); ++ auto array = Java_AdblockElement_getChildren(env, obj_); ++ ++ if (!array.is_null()) { ++ jsize array_length = env->GetArrayLength(array.obj()); ++ children_.reserve(array_length); ++ ++ for (jsize n = 0; n != array_length; ++n) { ++ children_.push_back(JavaElement( ++ env, ScopedJavaGlobalRef( ++ env, env->GetObjectArrayElement(array.obj(), n)))); ++ } ++ } ++ } ++ ++ res.reserve(children_.size()); ++ std::transform(children_.begin(), children_.end(), std::back_inserter(res), ++ [](const auto& cur) { return &cur; }); ++ ++ return res; ++ } ++ ++ private: ++ ScopedJavaGlobalRef obj_; ++ mutable std::vector children_; ++}; ++ ++void ComposeFilterSuggestionsResult( ++ const base::android::ScopedJavaGlobalRef& element, ++ const base::android::ScopedJavaGlobalRef& callback, ++ const std::vector& filters) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ JNIEnv* env = AttachCurrentThread(); ++ auto j_filters = ToJavaArrayOfStrings(env, filters); ++ Java_AdblockComposeFilterSuggestionsCallback_onDone(env, callback, element, ++ j_filters); ++} ++ ++constexpr int kNoId = -1; ++ ++int GetTabId(content::RenderFrameHost* render_frame_host) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ ++ auto* web_contents = ++ content::WebContents::FromRenderFrameHost(render_frame_host); ++ if (!web_contents) ++ return kNoId; ++ ++ auto* tab = TabAndroid::FromWebContents(web_contents); ++ if (!tab) ++ return kNoId; ++ ++ return tab->GetAndroidId(); ++} ++ ++ScopedJavaLocalRef ToJava(JNIEnv* env, ++ ScopedJavaLocalRef& url_class, ++ jmethodID& url_constructor, ++ const std::string& url, ++ const std::string& title, ++ const std::vector& languages) { ++ ScopedJavaLocalRef url_param( ++ env, env->NewObject(url_class.obj(), url_constructor, ++ ConvertUTF8ToJavaString(env, url).obj())); ++ CheckException(env); ++ return Java_Subscription_Constructor(env, url_param, ++ ConvertUTF8ToJavaString(env, title), ++ ToJavaArrayOfStrings(env, languages)); ++} ++ ++std::vector> CSubscriptionsToJObjects( ++ JNIEnv* env, ++ const std::vector>& subscriptions) { ++ ScopedJavaLocalRef url_class = GetClass(env, "java/net/URL"); ++ jmethodID url_constructor = MethodID::Get( ++ env, url_class.obj(), "", "(Ljava/lang/String;)V"); ++ std::vector> jobjects; ++ jobjects.reserve(subscriptions.size()); ++ for (auto& sub : subscriptions) { ++ jobjects.push_back(ToJava(env, url_class, url_constructor, ++ sub->GetSourceUrl().spec(), sub->GetTitle(), ++ std::vector{})); ++ } ++ return jobjects; ++} ++ ++std::vector> CSubscriptionsToJObjects( ++ JNIEnv* env, ++ std::vector& subscriptions) { ++ ScopedJavaLocalRef url_class = GetClass(env, "java/net/URL"); ++ jmethodID url_constructor = MethodID::Get( ++ env, url_class.obj(), "", "(Ljava/lang/String;)V"); ++ std::vector> jobjects; ++ jobjects.reserve(subscriptions.size()); ++ for (auto& sub : subscriptions) { ++ if (sub.ui_visibility == SubscriptionUiVisibility::Visible) { ++ // The checks here are when one makes f.e. adblock:custom visible ++ DCHECK(sub.url.is_valid()); ++ if (sub.url.is_valid()) { ++ jobjects.push_back(ToJava(env, url_class, url_constructor, ++ sub.url.spec(), sub.title, sub.languages)); ++ } ++ } ++ } ++ return jobjects; ++} ++ ++std::vector SubscriptionsToUrls( ++ const std::vector>& subscriptions) { ++ std::vector urls; ++ urls.reserve(subscriptions.size()); ++ base::ranges::transform( ++ subscriptions, std::back_inserter(urls), ++ [](const auto& sub) { return sub->GetSourceUrl().spec(); }); ++ return urls; ++} ++ ++} // namespace ++ ++AdblockJNI::AdblockJNI(ResourceClassificationRunner* classification_runner, ++ AdblockController* controller) ++ : classification_runner_(classification_runner), controller_(controller) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ if (classification_runner_) // Might not be there in unit tests. ++ classification_runner_->AddObserver(this); ++ if (controller_) ++ controller_->AddObserver(this); ++} ++ ++AdblockJNI::~AdblockJNI() { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ if (controller_) ++ controller_->RemoveObserver(this); ++ if (classification_runner_) ++ classification_runner_->RemoveObserver(this); ++} ++ ++void AdblockJNI::Bind(JavaObjectWeakGlobalRef weak_java_controller) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ weak_java_controller_ = weak_java_controller; ++} ++ ++void AdblockJNI::OnAdMatched(const GURL& url, ++ FilterMatchResult result, ++ const std::vector& parent_frame_urls, ++ ContentType content_type, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ DCHECK(render_frame_host); ++ DCHECK(result == FilterMatchResult::kBlockRule || ++ result == FilterMatchResult::kAllowRule); ++ if (!has_counters_observers_) ++ return; ++ const bool was_blocked = result == FilterMatchResult::kBlockRule; ++ DVLOG(3) << "[eyeo] Ad matched " << url << "(type: " << content_type ++ << (was_blocked ? ", blocked" : ", allowed") << ")"; ++ JNIEnv* env = AttachCurrentThread(); ++ ++ ScopedJavaLocalRef obj = weak_java_controller_.get(env); ++ if (obj.is_null()) ++ return; ++ ++ ScopedJavaLocalRef j_url = ConvertUTF8ToJavaString(env, url.spec()); ++ ScopedJavaLocalRef j_parents = ++ ToJavaArrayOfStrings(env, adblock::utils::ConvertURLs(parent_frame_urls)); ++ ScopedJavaLocalRef j_subscription = ++ ConvertUTF8ToJavaString(env, subscription.spec()); ++ int tab_id = GetTabId(render_frame_host); ++ Java_AdblockController_adMatchedCallback( ++ env, obj, j_url, was_blocked, j_parents, j_subscription, ++ static_cast(content_type), tab_id); ++} ++ ++void AdblockJNI::OnPageAllowed(const GURL& url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ DCHECK(render_frame_host); ++ if (!has_counters_observers_) ++ return; ++ DVLOG(3) << "[eyeo] Page allowed " << url; ++ JNIEnv* env = AttachCurrentThread(); ++ ++ ScopedJavaLocalRef obj = weak_java_controller_.get(env); ++ if (obj.is_null()) ++ return; ++ ++ ScopedJavaLocalRef j_url = ConvertUTF8ToJavaString(env, url.spec()); ++ ScopedJavaLocalRef j_subscription = ++ ConvertUTF8ToJavaString(env, subscription.spec()); ++ int tab_id = GetTabId(render_frame_host); ++ Java_AdblockController_pageAllowedCallback(env, obj, j_url, j_subscription, ++ tab_id); ++} ++ ++void AdblockJNI::OnPopupMatched(const GURL& url, ++ FilterMatchResult result, ++ const GURL& opener_url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ DCHECK(render_frame_host); ++ DCHECK(result == FilterMatchResult::kBlockRule || ++ result == FilterMatchResult::kAllowRule); ++ if (!has_counters_observers_) ++ return; ++ const bool was_blocked = result == FilterMatchResult::kBlockRule; ++ DVLOG(3) << "[eyeo] Popup matched " << url ++ << (was_blocked ? ", blocked" : ", allowed"); ++ JNIEnv* env = AttachCurrentThread(); ++ ++ ScopedJavaLocalRef obj = weak_java_controller_.get(env); ++ if (obj.is_null()) ++ return; ++ ++ ScopedJavaLocalRef j_url = ConvertUTF8ToJavaString(env, url.spec()); ++ ScopedJavaLocalRef j_opener = ++ ConvertUTF8ToJavaString(env, opener_url.spec()); ++ ScopedJavaLocalRef j_subscription = ++ ConvertUTF8ToJavaString(env, subscription.spec()); ++ int tab_id = GetTabId(render_frame_host); ++ Java_AdblockController_popupMatchedCallback(env, obj, j_url, was_blocked, ++ j_opener, j_subscription, tab_id); ++} ++ ++void AdblockJNI::SetHasAdblockCountersObservers(bool has_observers) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ has_counters_observers_ = has_observers; ++} ++ ++void AdblockJNI::OnSubscriptionUpdated(const GURL& url) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ JNIEnv* env = AttachCurrentThread(); ++ ScopedJavaLocalRef obj = weak_java_controller_.get(env); ++ if (obj.is_null()) ++ return; ++ ++ ScopedJavaLocalRef j_url = ConvertUTF8ToJavaString(env, url.spec()); ++ Java_AdblockController_subscriptionUpdatedCallback(env, obj, j_url); ++} ++ ++} // namespace adblock ++ ++static void JNI_AdblockController_SetHasAdblockCountersObservers( ++ JNIEnv* env, ++ const base::android::JavaParamRef& jcaller, ++ jboolean has_observers) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetJNI()->SetHasAdblockCountersObservers(has_observers == JNI_TRUE); ++} ++ ++static void JNI_AdblockController_Bind( ++ JNIEnv* env, ++ const base::android::JavaParamRef& caller) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ JavaObjectWeakGlobalRef weak_controller_ref(env, caller); ++ adblock::GetJNI()->Bind(weak_controller_ref); ++} ++ ++static jboolean JNI_AdblockController_IsAdblockEnabled(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ DCHECK(adblock::GetController()); ++ return adblock::GetController()->IsAdblockEnabled() ? JNI_TRUE : JNI_FALSE; ++} ++ ++static jboolean JNI_AdblockController_IsAcceptableAdsEnabled(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ DCHECK(adblock::GetController()); ++ return adblock::GetController()->IsAcceptableAdsEnabled() ? JNI_TRUE ++ : JNI_FALSE; ++} ++ ++static void JNI_AdblockController_SetAdblockEnabled(JNIEnv* env, ++ jboolean j_aa_enabled) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ DCHECK(adblock::GetController()); ++ return adblock::GetController()->SetAdblockEnabled(j_aa_enabled == JNI_TRUE); ++} ++ ++static void JNI_AdblockController_SetAcceptableAdsEnabled( ++ JNIEnv* env, ++ jboolean j_aa_enabled) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ DCHECK(adblock::GetController()); ++ return adblock::GetController()->SetAcceptableAdsEnabled(j_aa_enabled == ++ JNI_TRUE); ++} ++ ++static void JNI_AdblockController_InstallSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->InstallSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetInstalledSubscriptions(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return ToJavaArrayOfObjects(env, ++ std::vector>{}); ++ ++ return ToJavaArrayOfObjects( ++ env, adblock::CSubscriptionsToJObjects( ++ env, adblock::GetController()->GetInstalledSubscriptions())); ++} ++ ++static void JNI_AdblockController_UninstallSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->UninstallSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static void JNI_AdblockController_SelectSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->SelectBuiltInSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetSelectedSubscriptions(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return ToJavaArrayOfStrings(env, std::vector{}); ++ ++ return ToJavaArrayOfStrings( ++ env, adblock::SubscriptionsToUrls( ++ adblock::GetController()->GetSelectedBuiltInSubscriptions())); ++} ++ ++static void JNI_AdblockController_UnselectSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ ++ adblock::GetController()->UnselectBuiltInSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static void JNI_AdblockController_AddCustomSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->AddCustomSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetCustomSubscriptions(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return ToJavaArrayOfStrings(env, std::vector{}); ++ ++ return ToJavaArrayOfStrings( ++ env, adblock::SubscriptionsToUrls( ++ adblock::GetController()->GetCustomSubscriptions())); ++} ++ ++static void JNI_AdblockController_RemoveCustomSubscription( ++ JNIEnv* env, ++ const base::android::JavaParamRef& url) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->RemoveCustomSubscription( ++ GURL{ConvertJavaStringToUTF8(url)}); ++} ++ ++static void JNI_AdblockController_AddAllowedDomain( ++ JNIEnv* env, ++ const base::android::JavaParamRef& domain) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->AddAllowedDomain(ConvertJavaStringToUTF8(domain)); ++} ++ ++static void JNI_AdblockController_RemoveAllowedDomain( ++ JNIEnv* env, ++ const base::android::JavaParamRef& domain) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return; ++ adblock::GetController()->RemoveAllowedDomain( ++ ConvertJavaStringToUTF8(domain)); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetAllowedDomains(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return ToJavaArrayOfStrings(env, std::vector{}); ++ ++ return ToJavaArrayOfStrings(env, ++ adblock::GetController()->GetAllowedDomains()); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetRecommendedSubscriptions(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ if (!adblock::GetController()) ++ return ToJavaArrayOfObjects(env, ++ std::vector>{}); ++ ++ auto list = adblock::GetController()->GetKnownSubscriptions(); ++ return ToJavaArrayOfObjects(env, ++ adblock::CSubscriptionsToJObjects(env, list)); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetSelectedSubscriptionVersion( ++ JNIEnv* env, ++ const base::android::JavaParamRef& subscription) { ++ const GURL url(ConvertJavaStringToUTF8(subscription)); ++ const auto built_in_subscriptions = ++ adblock::GetController()->GetSelectedBuiltInSubscriptions(); ++ auto it = base::ranges::find(built_in_subscriptions, url, ++ &adblock::Subscription::GetSourceUrl); ++ if (it == built_in_subscriptions.end()) { ++ const auto custom_subscriptions = ++ adblock::GetController()->GetCustomSubscriptions(); ++ it = base::ranges::find(custom_subscriptions, url, ++ &adblock::Subscription::GetSourceUrl); ++ if (it == custom_subscriptions.end()) ++ return ConvertUTF8ToJavaString(env, {}); ++ } ++ ScopedJavaLocalRef j_version = ++ ConvertUTF8ToJavaString(env, (*it)->GetCurrentVersion()); ++ return j_version; ++} ++ ++static void JNI_AdblockController_ComposeFilterSuggestions( ++ JNIEnv* env, ++ const base::android::JavaParamRef& element, ++ const base::android::JavaParamRef& callback) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ // TODO implement ComposeFilterSuggestions in flatbuffer core: DPD-699 ++ // This is currently not doing the right thing. ++ base::android::ScopedJavaGlobalRef element_ref(element); ++ base::android::ScopedJavaGlobalRef callback_ref(callback); ++ adblock::ComposeFilterSuggestionsResult(element_ref, callback_ref, {}); ++} ++ ++static void JNI_AdblockController_AddCustomFilter( ++ JNIEnv* env, ++ const base::android::JavaParamRef& filter) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ auto* controller = adblock::GetController(); ++ if (!controller) ++ return; ++ ++ controller->AddCustomFilter(ConvertJavaStringToUTF8(filter)); ++} ++ ++static void JNI_AdblockController_RemoveCustomFilter( ++ JNIEnv* env, ++ const base::android::JavaParamRef& filter) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ auto* controller = adblock::GetController(); ++ if (!controller) ++ return; ++ ++ controller->RemoveCustomFilter(ConvertJavaStringToUTF8(filter)); ++} ++ ++static base::android::ScopedJavaLocalRef ++JNI_AdblockController_GetCustomFilters(JNIEnv* env) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ auto* controller = adblock::GetController(); ++ if (!controller) ++ return ToJavaArrayOfStrings(env, std::vector{}); ++ ++ return ToJavaArrayOfStrings(env, controller->GetCustomFilters()); ++} +diff --git a/chrome/browser/android/adblock/adblock_jni.h b/chrome/browser/android/adblock/adblock_jni.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/android/adblock/adblock_jni.h +@@ -0,0 +1,74 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ANDROID_ADBLOCK_ADBLOCK_JNI_H_ ++#define CHROME_BROWSER_ANDROID_ADBLOCK_ADBLOCK_JNI_H_ ++ ++#include ++ ++#include "base/android/jni_weak_ref.h" ++#include "components/adblock/content/browser/resource_classification_runner.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/keyed_service/core/keyed_service.h" ++ ++namespace content { ++class BrowserContext; ++} ++ ++namespace adblock { ++ ++class AdblockJNI : public ResourceClassificationRunner::Observer, ++ public AdblockController::Observer, ++ public KeyedService { ++ public: ++ AdblockJNI(ResourceClassificationRunner* classification_runner, ++ AdblockController* controller); ++ ~AdblockJNI() override; ++ ++ void Bind(JavaObjectWeakGlobalRef weak_java_controller); ++ void SetHasAdblockCountersObservers(bool has_observers); ++ ++ // ResourceClassificationRunner::Observer: ++ void OnAdMatched(const GURL& url, ++ FilterMatchResult result, ++ const std::vector& parent_frame_urls, ++ ContentType content_type, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override; ++ void OnPageAllowed(const GURL& url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) final; ++ void OnPopupMatched(const GURL& url, ++ FilterMatchResult match_result, ++ const GURL& opener_url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override; ++ ++ // AdblockController::Observer: ++ void OnSubscriptionUpdated(const GURL& url) override; ++ ++ private: ++ SEQUENCE_CHECKER(sequence_checker_); ++ ResourceClassificationRunner* classification_runner_; ++ AdblockController* controller_; ++ bool has_counters_observers_{false}; ++ JavaObjectWeakGlobalRef weak_java_controller_; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ANDROID_ADBLOCK_ADBLOCK_JNI_H_ +diff --git a/chrome/browser/android/adblock/adblock_jni_factory.cc b/chrome/browser/android/adblock/adblock_jni_factory.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/android/adblock/adblock_jni_factory.cc +@@ -0,0 +1,75 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#include "chrome/browser/android/adblock/adblock_jni_factory.h" ++ ++#include ++ ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/android/adblock/adblock_jni.h" ++#include "chrome/browser/profiles/incognito_helpers.h" ++#include "chrome/browser/profiles/profile.h" ++#include "components/keyed_service/content/browser_context_dependency_manager.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++// static ++AdblockJNI* AdblockJNIFactory::GetForBrowserContext( ++ content::BrowserContext* context) { ++ return static_cast( ++ GetInstance()->GetServiceForBrowserContext(context, true)); ++} ++// static ++AdblockJNIFactory* AdblockJNIFactory::GetInstance() { ++ static base::NoDestructor instance; ++ return instance.get(); ++} ++ ++AdblockJNIFactory::AdblockJNIFactory() ++ : BrowserContextKeyedServiceFactory( ++ "AdblockJNI", ++ BrowserContextDependencyManager::GetInstance()) { ++ DependsOn(AdblockControllerFactory::GetInstance()); ++ DependsOn(ResourceClassificationRunnerFactory::GetInstance()); ++} ++ ++AdblockJNIFactory::~AdblockJNIFactory() = default; ++ ++KeyedService* AdblockJNIFactory::BuildServiceInstanceFor( ++ content::BrowserContext* context) const { ++ return new AdblockJNI( ++ ResourceClassificationRunnerFactory::GetForBrowserContext(context), ++ AdblockControllerFactory::GetForBrowserContext(context)); ++} ++ ++content::BrowserContext* AdblockJNIFactory::GetBrowserContextToUse( ++ content::BrowserContext* context) const { ++ return chrome::GetBrowserContextRedirectedInIncognito(context); ++} ++ ++bool AdblockJNIFactory::ServiceIsCreatedWithBrowserContext() const { ++ // This avoids manual instantiation in chrome_browser_main.cc ++ return true; ++} ++ ++bool AdblockJNIFactory::ServiceIsNULLWhileTesting() const { ++ return true; ++} ++ ++} // namespace adblock +diff --git a/chrome/browser/android/adblock/adblock_jni_factory.h b/chrome/browser/android/adblock/adblock_jni_factory.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/android/adblock/adblock_jni_factory.h +@@ -0,0 +1,50 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++ ++#ifndef CHROME_BROWSER_ADBLOCK_ADBLOCK_JNI_FACTORY_H_ ++#define CHROME_BROWSER_ADBLOCK_ADBLOCK_JNI_FACTORY_H_ ++ ++#include "base/no_destructor.h" ++#include "components/keyed_service/content/browser_context_keyed_service_factory.h" ++#include "content/public/browser/browser_context.h" ++ ++namespace adblock { ++ ++class AdblockJNI; ++class AdblockJNIFactory : public BrowserContextKeyedServiceFactory { ++ public: ++ public: ++ static AdblockJNI* GetForBrowserContext(content::BrowserContext* context); ++ static AdblockJNIFactory* GetInstance(); ++ ++ private: ++ friend class base::NoDestructor; ++ AdblockJNIFactory(); ++ ~AdblockJNIFactory() override; ++ ++ // BrowserContextKeyedServiceFactory: ++ KeyedService* BuildServiceInstanceFor( ++ content::BrowserContext* context) const override; ++ content::BrowserContext* GetBrowserContextToUse( ++ content::BrowserContext* context) const override; ++ bool ServiceIsCreatedWithBrowserContext() const override; ++ bool ServiceIsNULLWhileTesting() const override; ++}; ++ ++} // namespace adblock ++ ++#endif // CHROME_BROWSER_ADBLOCK_ADBLOCK_JNI_FACTORY_H_ +diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc ++++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +@@ -1,6 +1,10 @@ + // Copyright 2014 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" + +@@ -101,6 +105,7 @@ const char* const kChromeSettingsSubPages[] = { + chrome::kImportDataSubPage, chrome::kManageProfileSubPage, + chrome::kPeopleSubPage, + #endif ++ chrome::kAdblockSubPage, + }; + #endif // BUILDFLAG(IS_ANDROID) + +diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc +--- a/chrome/browser/client_hints/client_hints_browsertest.cc ++++ b/chrome/browser/client_hints/client_hints_browsertest.cc +@@ -1,6 +1,10 @@ + // Copyright 2017 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include + #include +@@ -505,8 +509,12 @@ class ClientHintsBrowserTest : public policy::PolicyTest { + feature_list->InitializeFromCommandLine( + "UserAgentClientHint,CriticalClientHint," + "AcceptCHFrame,PrefersColorSchemeClientHintHeader," +- "PrefersReducedMotionClientHintHeader", +- ""); ++ "PrefersReducedMotionClientHintHeader," ++ "", ++ // Disabling AdblockPlus because the async implementation of ++ // AdblockURLLoaderThrottle::WillStartRequest confuses ++ // ThirdPartyURLLoaderInterceptor. ++ "AdblockPlus"); + return feature_list; + } + +diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn +--- a/chrome/browser/extensions/BUILD.gn ++++ b/chrome/browser/extensions/BUILD.gn +@@ -1,6 +1,10 @@ + # Copyright 2014 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. ++ + + import("//build/config/chromebox_for_meetings/buildflags.gni") + import("//build/config/chromeos/ui_mode.gni") +@@ -47,6 +51,8 @@ static_library("extensions") { + # here. + "api/activity_log_private/activity_log_private_api.cc", + "api/activity_log_private/activity_log_private_api.h", ++ "api/adblock_private/adblock_private_api.cc", ++ "api/adblock_private/adblock_private_api.h", + "api/autofill_private/autofill_private_api.cc", + "api/autofill_private/autofill_private_api.h", + "api/autofill_private/autofill_private_event_router.cc", +@@ -797,6 +803,7 @@ static_library("extensions") { + "//chrome/browser/safe_browsing:metrics_collector", + "//chrome/browser/ui/tabs:tab_enums", + "//chrome/browser/web_applications", ++ "//components/adblock/content:browser", + "//components/autofill_assistant/browser/public", + "//components/cbor:cbor", + "//components/commerce/core:pref_names", +diff --git a/chrome/browser/extensions/api/BUILD.gn b/chrome/browser/extensions/api/BUILD.gn +--- a/chrome/browser/extensions/api/BUILD.gn ++++ b/chrome/browser/extensions/api/BUILD.gn +@@ -1,6 +1,10 @@ + # Copyright 2018 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. ++ + + import("//chrome/common/extensions/api/api_sources.gni") + import("//chrome/common/features.gni") +@@ -50,6 +54,7 @@ function_registration("api_registration") { + # include generated headers from these targets. + # TODO(brettw) this should be made unnecessary if possible. + "//chrome/common/extensions/api", ++ "//components/adblock/content:browser", + "//components/sync", + "//skia", + "//third_party/metrics_proto", +diff --git a/chrome/browser/extensions/api/adblock_private/adblock_private_api.cc b/chrome/browser/extensions/api/adblock_private/adblock_private_api.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/extensions/api/adblock_private/adblock_private_api.cc +@@ -0,0 +1,740 @@ ++// This file is part of eyeo Chromium SDK, ++// Copyright (C) 2006-present eyeo GmbH ++// ++// eyeo Chromium SDK is free software: you can redistribute it and/or modify ++// it under the terms of the GNU General Public License version 3 as ++// published by the Free Software Foundation. ++// ++// eyeo Chromium SDK is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with eyeo Chromium SDK. If not, see . ++ ++#include "chrome/browser/extensions/api/adblock_private/adblock_private_api.h" ++ ++#include "base/containers/flat_map.h" ++#include "base/logging.h" ++#include "base/no_destructor.h" ++#include "base/time/time_to_iso8601.h" ++#include "base/values.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/adblock/session_stats_factory.h" ++#include "chrome/browser/extensions/extension_tab_util.h" ++#include "chrome/common/extensions/api/tabs.h" ++#include "components/adblock/content/browser/resource_classification_runner.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_utils.h" ++#include "components/adblock/core/common/content_type.h" ++#include "components/adblock/core/session_stats.h" ++#include "components/sessions/core/session_id.h" ++#include "content/public/browser/web_contents.h" ++#include "url/gurl.h" ++ ++namespace extensions { ++ ++namespace { ++ ++enum class BuiltInSubscriptionAction { kSelect, kUnselect }; ++ ++std::string RunBuiltInSubscriptionAction( ++ BuiltInSubscriptionAction action, ++ content::BrowserContext* browser_context, ++ const GURL& url) { ++ if (!url.is_valid()) ++ return "Invalid URL"; ++ auto* controller = ++ adblock::AdblockControllerFactory::GetForBrowserContext(browser_context); ++ auto recommended = controller->GetKnownSubscriptions(); ++ if (!recommended.empty()) { ++ auto item = ++ std::find_if(recommended.begin(), recommended.end(), ++ [&url](const adblock::KnownSubscriptionInfo& recommended) { ++ return recommended.url == url; ++ }); ++ if (item == recommended.end()) ++ return "Not a built-in subscription"; ++ } ++ ++ switch (action) { ++ case BuiltInSubscriptionAction::kSelect: ++ controller->SelectBuiltInSubscription(url); ++ break; ++ case BuiltInSubscriptionAction::kUnselect: ++ controller->UnselectBuiltInSubscription(url); ++ break; ++ default: ++ NOTREACHED(); ++ } ++ ++ return {}; ++} ++ ++enum class CustomSubscriptionAction { kAdd, kRemove }; ++ ++std::string RunCustomSubscriptionAction( ++ CustomSubscriptionAction action, ++ content::BrowserContext* browser_context, ++ const GURL& url) { ++ if (!url.is_valid()) ++ return "Invalid URL"; ++ auto* controller = ++ adblock::AdblockControllerFactory::GetForBrowserContext(browser_context); ++ switch (action) { ++ case CustomSubscriptionAction::kAdd: ++ controller->AddCustomSubscription(url); ++ break; ++ case CustomSubscriptionAction::kRemove: ++ controller->RemoveCustomSubscription(url); ++ break; ++ default: ++ NOTREACHED(); ++ } ++ ++ return {}; ++} ++ ++enum class SubscriptionAction { kInstall, kUninstall }; ++ ++std::string RunSubscriptionAction(SubscriptionAction action, ++ content::BrowserContext* browser_context, ++ const GURL& url) { ++ if (!url.is_valid()) ++ return "Invalid URL"; ++ auto* controller = ++ adblock::AdblockControllerFactory::GetForBrowserContext(browser_context); ++ switch (action) { ++ case SubscriptionAction::kInstall: ++ controller->InstallSubscription(url); ++ break; ++ case SubscriptionAction::kUninstall: ++ controller->UninstallSubscription(url); ++ break; ++ default: ++ NOTREACHED(); ++ } ++ ++ return {}; ++} ++ ++std::vector CopySessionsStats( ++ const std::map& source) { ++ std::vector result; ++ for (auto& entry : source) { ++ api::adblock_private::SessionStatsEntry js_entry; ++ js_entry.url = entry.first.spec(); ++ js_entry.count = entry.second; ++ result.emplace_back(std::move(js_entry)); ++ } ++ return result; ++} ++ ++std::string SubscriptionInstallationStateToString( ++ adblock::Subscription::InstallationState state) { ++ using State = adblock::Subscription::InstallationState; ++ switch (state) { ++ case State::Installed: ++ return "Installed"; ++ case State::Installing: ++ return "Installing"; ++ case State::Preloaded: ++ return "Preloaded"; ++ } ++ NOTREACHED(); ++ return ""; ++} ++ ++std::vector CopySubscriptions( ++ const std::vector> ++ current_subscriptions) { ++ std::vector result; ++ for (auto& sub : current_subscriptions) { ++ api::adblock_private::Subscription js_sub; ++ js_sub.url = sub->GetSourceUrl().spec(); ++ js_sub.title = sub->GetTitle(); ++ js_sub.current_version = sub->GetCurrentVersion(); ++ js_sub.installation_state = ++ SubscriptionInstallationStateToString(sub->GetInstallationState()); ++ js_sub.last_installation_time = ++ base::TimeToISO8601(sub->GetInstallationTime()); ++ result.emplace_back(std::move(js_sub)); ++ } ++ return result; ++} ++ ++} // namespace ++ ++template <> ++void BrowserContextKeyedAPIFactory< ++ AdblockPrivateAPI>::DeclareFactoryDependencies() { ++ DependsOn(adblock::AdblockControllerFactory::GetInstance()); ++ DependsOn(adblock::ResourceClassificationRunnerFactory::GetInstance()); ++ DependsOn(adblock::SessionStatsFactory::GetInstance()); ++} ++ ++// static ++BrowserContextKeyedAPIFactory* ++AdblockPrivateAPI::GetFactoryInstance() { ++ static base::NoDestructor> ++ instance; ++ return instance.get(); ++} ++ ++class AdblockPrivateAPI::AdblockAPIEventRouter ++ : public adblock::ResourceClassificationRunner::Observer, ++ public adblock::AdblockController::Observer { ++ public: ++ explicit AdblockAPIEventRouter(content::BrowserContext* context) ++ : context_(context) { ++ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context) ++ ->AddObserver(this); ++ adblock::AdblockControllerFactory::GetForBrowserContext(context) ++ ->AddObserver(this); ++ } ++ ++ ~AdblockAPIEventRouter() override { ++ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context_) ++ ->RemoveObserver(this); ++ adblock::AdblockControllerFactory::GetForBrowserContext(context_) ++ ->RemoveObserver(this); ++ } ++ ++ // adblock::ResourceClassificationRunner::Observer: ++ void OnAdMatched(const GURL& url, ++ adblock::FilterMatchResult match_result, ++ const std::vector& parent_frame_urls, ++ adblock::ContentType content_type, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override { ++ std::unique_ptr event; ++ api::adblock_private::AdInfo info = ++ CreateAdInfoObject(url, subscription, render_frame_host); ++ info.parent_frame_urls = adblock::utils::ConvertURLs(parent_frame_urls); ++ info.content_type = adblock::ContentTypeToString(content_type); ++ ++ if (match_result == adblock::FilterMatchResult::kBlockRule) { ++ event = std::make_unique( ++ events::ADBLOCK_PRIVATE_AD_BLOCKED, ++ api::adblock_private::OnAdBlocked::kEventName, ++ api::adblock_private::OnAdBlocked::Create(info), context_); ++ } else { ++ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule); ++ event = std::make_unique( ++ events::ADBLOCK_PRIVATE_AD_ALLOWED, ++ api::adblock_private::OnAdAllowed::kEventName, ++ api::adblock_private::OnAdAllowed::Create(info), context_); ++ } ++ ++ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event)); ++ } ++ ++ void OnPageAllowed(const GURL& url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override { ++ api::adblock_private::AdInfo info = ++ CreateAdInfoObject(url, subscription, render_frame_host); ++ info.parent_frame_urls = std::vector{}; ++ info.content_type = ""; ++ ++ std::unique_ptr event = std::make_unique( ++ events::ADBLOCK_PRIVATE_PAGE_ALLOWED, ++ api::adblock_private::OnPageAllowed::kEventName, ++ api::adblock_private::OnPageAllowed::Create(info), context_); ++ ++ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event)); ++ } ++ ++ void OnPopupMatched(const GURL& url, ++ adblock::FilterMatchResult match_result, ++ const GURL& opener_url, ++ content::RenderFrameHost* render_frame_host, ++ const GURL& subscription) override { ++ std::unique_ptr event; ++ api::adblock_private::AdInfo info = ++ CreateAdInfoObject(url, subscription, render_frame_host); ++ info.parent_frame_urls = std::vector{opener_url.spec()}; ++ info.content_type = ""; ++ ++ if (match_result == adblock::FilterMatchResult::kBlockRule) { ++ event = std::make_unique( ++ events::ADBLOCK_PRIVATE_POPUP_BLOCKED, ++ api::adblock_private::OnPopupBlocked::kEventName, ++ api::adblock_private::OnPopupBlocked::Create(info), context_); ++ } else { ++ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule); ++ event = std::make_unique( ++ events::ADBLOCK_PRIVATE_POPUP_ALLOWED, ++ api::adblock_private::OnPopupAllowed::kEventName, ++ api::adblock_private::OnPopupAllowed::Create(info), context_); ++ } ++ ++ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event)); ++ } ++ ++ // adblock::AdblockController::Observer: ++ void OnSubscriptionUpdated(const GURL& url) override { ++ std::unique_ptr event = std::make_unique( ++ events::ADBLOCK_PRIVATE_SUBSCRIPTION_UPDATED, ++ api::adblock_private::OnSubscriptionUpdated::kEventName, ++ api::adblock_private::OnSubscriptionUpdated::Create(url.spec()), ++ context_); ++ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event)); ++ } ++ ++ private: ++ api::adblock_private::AdInfo CreateAdInfoObject( ++ const GURL& url, ++ const GURL& subscription, ++ content::RenderFrameHost* render_frame_host) { ++ DCHECK(render_frame_host); ++ api::adblock_private::AdInfo info; ++ info.url = url.spec(); ++ info.subscription = subscription.spec(); ++ info.tab_id = api::tabs::TAB_ID_NONE; ++ info.window_id = SessionID::InvalidValue().id(); ++ const content::WebContents* wc = ++ content::WebContents::FromRenderFrameHost(render_frame_host); ++ if (wc) { ++ info.tab_id = ExtensionTabUtil::GetTabId(wc); ++ info.window_id = ExtensionTabUtil::GetWindowIdOfTab(wc); ++ } ++ return info; ++ } ++ ++ content::BrowserContext* context_; ++}; ++ ++void AdblockPrivateAPI::Shutdown() { ++ // EventRouter can be null in tests ++ if (EventRouter::Get(context_)) { ++ EventRouter::Get(context_)->UnregisterObserver(this); ++ } ++ event_router_.reset(); ++} ++ ++// static ++AdblockPrivateAPI* AdblockPrivateAPI::Get(content::BrowserContext* context) { ++ return GetFactoryInstance()->Get(context); ++} ++ ++AdblockPrivateAPI::AdblockPrivateAPI(content::BrowserContext* context) ++ : context_(context) { ++ // EventRouter can be null in tests ++ if (EventRouter::Get(context_)) { ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnAdAllowed::kEventName); ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnAdBlocked::kEventName); ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnPageAllowed::kEventName); ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnPopupAllowed::kEventName); ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnPopupBlocked::kEventName); ++ EventRouter::Get(context_)->RegisterObserver( ++ this, api::adblock_private::OnSubscriptionUpdated::kEventName); ++ } ++ adblock::SessionStatsFactory::GetForBrowserContext(context) ++ ->StartCollectingStats(); ++} ++ ++AdblockPrivateAPI::~AdblockPrivateAPI() = default; ++ ++void AdblockPrivateAPI::OnListenerAdded( ++ const extensions::EventListenerInfo& details) { ++ event_router_ = ++ std::make_unique(context_); ++ EventRouter::Get(context_)->UnregisterObserver(this); ++} ++ ++namespace api { ++ ++AdblockPrivateSetEnabledFunction::AdblockPrivateSetEnabledFunction() {} ++ ++AdblockPrivateSetEnabledFunction::~AdblockPrivateSetEnabledFunction() {} ++ ++ExtensionFunction::ResponseAction AdblockPrivateSetEnabledFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::SetEnabled::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->SetAdblockEnabled(params->enabled); ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateIsEnabledFunction::AdblockPrivateIsEnabledFunction() {} ++ ++AdblockPrivateIsEnabledFunction::~AdblockPrivateIsEnabledFunction() {} ++ ++ExtensionFunction::ResponseAction AdblockPrivateIsEnabledFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow( ++ ArgumentList(api::adblock_private::IsEnabled::Results::Create( ++ controller->IsAdblockEnabled()))); ++} ++ ++AdblockPrivateSetAcceptableAdsEnabledFunction:: ++ AdblockPrivateSetAcceptableAdsEnabledFunction() {} ++ ++AdblockPrivateSetAcceptableAdsEnabledFunction:: ++ ~AdblockPrivateSetAcceptableAdsEnabledFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateSetAcceptableAdsEnabledFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::SetAcceptableAdsEnabled::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->SetAcceptableAdsEnabled(params->enabled); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateIsAcceptableAdsEnabledFunction:: ++ AdblockPrivateIsAcceptableAdsEnabledFunction() {} ++ ++AdblockPrivateIsAcceptableAdsEnabledFunction:: ++ ~AdblockPrivateIsAcceptableAdsEnabledFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateIsAcceptableAdsEnabledFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow(ArgumentList( ++ api::adblock_private::IsAcceptableAdsEnabled::Results::Create( ++ controller->IsAcceptableAdsEnabled()))); ++} ++ ++AdblockPrivateGetBuiltInSubscriptionsFunction:: ++ AdblockPrivateGetBuiltInSubscriptionsFunction() {} ++ ++AdblockPrivateGetBuiltInSubscriptionsFunction:: ++ ~AdblockPrivateGetBuiltInSubscriptionsFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetBuiltInSubscriptionsFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ auto recommended = controller->GetKnownSubscriptions(); ++ std::vector result; ++ for (auto& recommended_one : recommended) { ++ if (recommended_one.ui_visibility == ++ adblock::SubscriptionUiVisibility::Visible) { ++ api::adblock_private::BuiltInSubscription js_recommended; ++ js_recommended.url = recommended_one.url.spec(); ++ js_recommended.title = recommended_one.title; ++ js_recommended.languages = recommended_one.languages; ++ result.emplace_back(std::move(js_recommended)); ++ } ++ } ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetBuiltInSubscriptions::Results::Create(result))); ++} ++ ++AdblockPrivateSelectBuiltInSubscriptionFunction:: ++ AdblockPrivateSelectBuiltInSubscriptionFunction() {} ++ ++AdblockPrivateSelectBuiltInSubscriptionFunction:: ++ ~AdblockPrivateSelectBuiltInSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateSelectBuiltInSubscriptionFunction::Run() { ++ std::unique_ptr ++ params(api::adblock_private::SelectBuiltInSubscription::Params::Create( ++ args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunBuiltInSubscriptionAction(BuiltInSubscriptionAction::kSelect, ++ browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateUnselectBuiltInSubscriptionFunction:: ++ AdblockPrivateUnselectBuiltInSubscriptionFunction() {} ++ ++AdblockPrivateUnselectBuiltInSubscriptionFunction:: ++ ~AdblockPrivateUnselectBuiltInSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateUnselectBuiltInSubscriptionFunction::Run() { ++ std::unique_ptr ++ params(api::adblock_private::UnselectBuiltInSubscription::Params::Create( ++ args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunBuiltInSubscriptionAction( ++ BuiltInSubscriptionAction::kUnselect, browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateGetSelectedBuiltInSubscriptionsFunction:: ++ AdblockPrivateGetSelectedBuiltInSubscriptionsFunction() {} ++ ++AdblockPrivateGetSelectedBuiltInSubscriptionsFunction:: ++ ~AdblockPrivateGetSelectedBuiltInSubscriptionsFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetSelectedBuiltInSubscriptionsFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetSelectedBuiltInSubscriptions::Results::Create( ++ CopySubscriptions(controller->GetSelectedBuiltInSubscriptions())))); ++} ++ ++AdblockPrivateAddCustomSubscriptionFunction:: ++ AdblockPrivateAddCustomSubscriptionFunction() {} ++ ++AdblockPrivateAddCustomSubscriptionFunction:: ++ ~AdblockPrivateAddCustomSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateAddCustomSubscriptionFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::AddCustomSubscription::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunCustomSubscriptionAction(CustomSubscriptionAction::kAdd, ++ browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateRemoveCustomSubscriptionFunction:: ++ AdblockPrivateRemoveCustomSubscriptionFunction() {} ++ ++AdblockPrivateRemoveCustomSubscriptionFunction:: ++ ~AdblockPrivateRemoveCustomSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateRemoveCustomSubscriptionFunction::Run() { ++ std::unique_ptr ++ params(api::adblock_private::RemoveCustomSubscription::Params::Create( ++ args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunCustomSubscriptionAction(CustomSubscriptionAction::kRemove, ++ browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateGetCustomSubscriptionsFunction:: ++ AdblockPrivateGetCustomSubscriptionsFunction() {} ++ ++AdblockPrivateGetCustomSubscriptionsFunction:: ++ ~AdblockPrivateGetCustomSubscriptionsFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetCustomSubscriptionsFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetCustomSubscriptions::Results::Create( ++ CopySubscriptions(controller->GetCustomSubscriptions())))); ++} ++ ++AdblockPrivateInstallSubscriptionFunction:: ++ AdblockPrivateInstallSubscriptionFunction() {} ++ ++AdblockPrivateInstallSubscriptionFunction:: ++ ~AdblockPrivateInstallSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateInstallSubscriptionFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::InstallSubscription::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunSubscriptionAction(SubscriptionAction::kInstall, ++ browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateUninstallSubscriptionFunction:: ++ AdblockPrivateUninstallSubscriptionFunction() {} ++ ++AdblockPrivateUninstallSubscriptionFunction:: ++ ~AdblockPrivateUninstallSubscriptionFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateUninstallSubscriptionFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::UninstallSubscription::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto url = GURL{params->url}; ++ auto status = RunSubscriptionAction(SubscriptionAction::kUninstall, ++ browser_context(), url); ++ if (!status.empty()) ++ return RespondNow(Error(status)); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateGetInstalledSubscriptionsFunction:: ++ AdblockPrivateGetInstalledSubscriptionsFunction() {} ++ ++AdblockPrivateGetInstalledSubscriptionsFunction:: ++ ~AdblockPrivateGetInstalledSubscriptionsFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetInstalledSubscriptionsFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetInstalledSubscriptions::Results::Create( ++ CopySubscriptions(controller->GetInstalledSubscriptions())))); ++} ++ ++AdblockPrivateAddAllowedDomainFunction:: ++ AdblockPrivateAddAllowedDomainFunction() {} ++ ++AdblockPrivateAddAllowedDomainFunction:: ++ ~AdblockPrivateAddAllowedDomainFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateAddAllowedDomainFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::AddAllowedDomain::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->AddAllowedDomain(params->domain); ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateRemoveAllowedDomainFunction:: ++ AdblockPrivateRemoveAllowedDomainFunction() {} ++ ++AdblockPrivateRemoveAllowedDomainFunction:: ++ ~AdblockPrivateRemoveAllowedDomainFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateRemoveAllowedDomainFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::RemoveAllowedDomain::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->RemoveAllowedDomain(params->domain); ++ ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateGetAllowedDomainsFunction:: ++ AdblockPrivateGetAllowedDomainsFunction() {} ++ ++AdblockPrivateGetAllowedDomainsFunction:: ++ ~AdblockPrivateGetAllowedDomainsFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetAllowedDomainsFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow( ++ ArgumentList(api::adblock_private::GetAllowedDomains::Results::Create( ++ controller->GetAllowedDomains()))); ++} ++ ++AdblockPrivateAddCustomFilterFunction::AdblockPrivateAddCustomFilterFunction() { ++} ++ ++AdblockPrivateAddCustomFilterFunction:: ++ ~AdblockPrivateAddCustomFilterFunction() {} ++ ++ExtensionFunction::ResponseAction AdblockPrivateAddCustomFilterFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::AddCustomFilter::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->AddCustomFilter(params->filter); ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateRemoveCustomFilterFunction:: ++ AdblockPrivateRemoveCustomFilterFunction() {} ++ ++AdblockPrivateRemoveCustomFilterFunction:: ++ ~AdblockPrivateRemoveCustomFilterFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetCustomFiltersFunction::Run() { ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ return RespondNow( ++ ArgumentList(api::adblock_private::GetCustomFilters::Results::Create( ++ controller->GetCustomFilters()))); ++} ++ ++AdblockPrivateGetCustomFiltersFunction:: ++ AdblockPrivateGetCustomFiltersFunction() {} ++ ++AdblockPrivateGetCustomFiltersFunction:: ++ ~AdblockPrivateGetCustomFiltersFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateRemoveCustomFilterFunction::Run() { ++ std::unique_ptr params( ++ api::adblock_private::RemoveCustomFilter::Params::Create(args())); ++ EXTENSION_FUNCTION_VALIDATE(params); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser_context()); ++ controller->RemoveCustomFilter(params->filter); ++ return RespondNow(NoArguments()); ++} ++ ++AdblockPrivateGetSessionAllowedAdsCountFunction:: ++ AdblockPrivateGetSessionAllowedAdsCountFunction() {} ++ ++AdblockPrivateGetSessionAllowedAdsCountFunction:: ++ ~AdblockPrivateGetSessionAllowedAdsCountFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetSessionAllowedAdsCountFunction::Run() { ++ auto* session_stats_ = ++ adblock::SessionStatsFactory::GetForBrowserContext(browser_context()); ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetSessionAllowedAdsCount::Results::Create( ++ CopySessionsStats(session_stats_->GetSessionAllowedAdsCount())))); ++} ++ ++AdblockPrivateGetSessionBlockedAdsCountFunction:: ++ AdblockPrivateGetSessionBlockedAdsCountFunction() {} ++ ++AdblockPrivateGetSessionBlockedAdsCountFunction:: ++ ~AdblockPrivateGetSessionBlockedAdsCountFunction() {} ++ ++ExtensionFunction::ResponseAction ++AdblockPrivateGetSessionBlockedAdsCountFunction::Run() { ++ auto* session_stats_ = ++ adblock::SessionStatsFactory::GetForBrowserContext(browser_context()); ++ return RespondNow(ArgumentList( ++ api::adblock_private::GetSessionAllowedAdsCount::Results::Create( ++ CopySessionsStats(session_stats_->GetSessionBlockedAdsCount())))); ++} ++ ++} // namespace api ++} // namespace extensions +diff --git a/chrome/browser/extensions/api/adblock_private/adblock_private_api.h b/chrome/browser/extensions/api/adblock_private/adblock_private_api.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/extensions/api/adblock_private/adblock_private_api.h +@@ -0,0 +1,447 @@ ++// This file is part of eyeo Chromium SDK, ++// Copyright (C) 2006-present eyeo GmbH ++// ++// eyeo Chromium SDK is free software: you can redistribute it and/or modify ++// it under the terms of the GNU General Public License version 3 as ++// published by the Free Software Foundation. ++// ++// eyeo Chromium SDK is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with eyeo Chromium SDK. If not, see . ++ ++#ifndef CHROME_BROWSER_EXTENSIONS_API_ADBLOCK_PRIVATE_ADBLOCK_PRIVATE_API_H_ ++#define CHROME_BROWSER_EXTENSIONS_API_ADBLOCK_PRIVATE_ADBLOCK_PRIVATE_API_H_ ++ ++#include "chrome/common/extensions/api/adblock_private.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "extensions/browser/browser_context_keyed_api_factory.h" ++#include "extensions/browser/event_router.h" ++#include "extensions/browser/extension_function.h" ++ ++class Profile; ++ ++namespace extensions { ++ ++class AdblockPrivateAPI : public BrowserContextKeyedAPI, ++ public EventRouter::Observer { ++ public: ++ static BrowserContextKeyedAPIFactory* GetFactoryInstance(); ++ ++ static AdblockPrivateAPI* Get(content::BrowserContext* context); ++ ++ explicit AdblockPrivateAPI(content::BrowserContext* context); ++ ~AdblockPrivateAPI() override; ++ friend class BrowserContextKeyedAPIFactory; ++ ++ // BrowserContextKeyedAPI implementation. ++ static const char* service_name() { return "AdblockPrivateAPI"; } ++ static const bool kServiceRedirectedInIncognito = true; ++ static const bool kServiceIsCreatedWithBrowserContext = true; ++ void Shutdown() override; ++ ++ // EventRouter::Observer: ++ void OnListenerAdded(const extensions::EventListenerInfo& details) override; ++ ++ private: ++ content::BrowserContext* context_; ++ class AdblockAPIEventRouter; ++ std::unique_ptr event_router_; ++}; ++ ++template <> ++void BrowserContextKeyedAPIFactory< ++ AdblockPrivateAPI>::DeclareFactoryDependencies(); ++ ++namespace api { ++ ++class AdblockPrivateSetEnabledFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.setEnabled", ++ ADBLOCKPRIVATE_SETENABLED) ++ AdblockPrivateSetEnabledFunction(); ++ ++ private: ++ ~AdblockPrivateSetEnabledFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateSetEnabledFunction(const AdblockPrivateSetEnabledFunction&) = ++ delete; ++ AdblockPrivateSetEnabledFunction& operator=( ++ const AdblockPrivateSetEnabledFunction&) = delete; ++}; ++ ++class AdblockPrivateIsEnabledFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.isEnabled", ++ ADBLOCKPRIVATE_ISENABLED) ++ AdblockPrivateIsEnabledFunction(); ++ ++ private: ++ ~AdblockPrivateIsEnabledFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateIsEnabledFunction(const AdblockPrivateIsEnabledFunction&) = ++ delete; ++ AdblockPrivateIsEnabledFunction& operator=( ++ const AdblockPrivateIsEnabledFunction&) = delete; ++}; ++ ++class AdblockPrivateSetAcceptableAdsEnabledFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.setAcceptableAdsEnabled", ++ ADBLOCKPRIVATE_SETACCEPTABLEADSENABLED) ++ AdblockPrivateSetAcceptableAdsEnabledFunction(); ++ ++ private: ++ ~AdblockPrivateSetAcceptableAdsEnabledFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateSetAcceptableAdsEnabledFunction( ++ const AdblockPrivateSetAcceptableAdsEnabledFunction&) = delete; ++ AdblockPrivateSetAcceptableAdsEnabledFunction& operator=( ++ const AdblockPrivateSetAcceptableAdsEnabledFunction&) = delete; ++}; ++ ++class AdblockPrivateIsAcceptableAdsEnabledFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.isAcceptableAdsEnabled", ++ ADBLOCKPRIVATE_ISACCEPTABLEADSENABLED) ++ AdblockPrivateIsAcceptableAdsEnabledFunction(); ++ ++ private: ++ ~AdblockPrivateIsAcceptableAdsEnabledFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateIsAcceptableAdsEnabledFunction( ++ const AdblockPrivateIsAcceptableAdsEnabledFunction&) = delete; ++ AdblockPrivateIsAcceptableAdsEnabledFunction& operator=( ++ const AdblockPrivateIsAcceptableAdsEnabledFunction&) = delete; ++}; ++ ++class AdblockPrivateGetBuiltInSubscriptionsFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getBuiltInSubscriptions", ++ ADBLOCKPRIVATE_GETBUILTINSUBSCRIPTIONS) ++ AdblockPrivateGetBuiltInSubscriptionsFunction(); ++ ++ private: ++ ~AdblockPrivateGetBuiltInSubscriptionsFunction() override; ++ ++ // ExtensionFunction: ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetBuiltInSubscriptionsFunction( ++ const AdblockPrivateGetBuiltInSubscriptionsFunction&) = delete; ++ AdblockPrivateGetBuiltInSubscriptionsFunction& operator=( ++ const AdblockPrivateGetBuiltInSubscriptionsFunction&) = delete; ++}; ++ ++class AdblockPrivateSelectBuiltInSubscriptionFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.selectBuiltInSubscription", ++ ADBLOCKPRIVATE_SELECTBUILTINSUBSCRIPTION) ++ AdblockPrivateSelectBuiltInSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateSelectBuiltInSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateSelectBuiltInSubscriptionFunction( ++ const AdblockPrivateSelectBuiltInSubscriptionFunction&) = delete; ++ AdblockPrivateSelectBuiltInSubscriptionFunction& operator=( ++ const AdblockPrivateSelectBuiltInSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateUnselectBuiltInSubscriptionFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.unselectBuiltInSubscription", ++ ADBLOCKPRIVATE_UNSELECTBUILTINSUBSCRIPTION) ++ AdblockPrivateUnselectBuiltInSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateUnselectBuiltInSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateUnselectBuiltInSubscriptionFunction( ++ const AdblockPrivateUnselectBuiltInSubscriptionFunction&) = delete; ++ AdblockPrivateUnselectBuiltInSubscriptionFunction& operator=( ++ const AdblockPrivateUnselectBuiltInSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateGetSelectedBuiltInSubscriptionsFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getSelectedBuiltInSubscriptions", ++ ADBLOCKPRIVATE_GETSELECTEDBUILTINSUBSCRIPTIONS) ++ AdblockPrivateGetSelectedBuiltInSubscriptionsFunction(); ++ ++ private: ++ ~AdblockPrivateGetSelectedBuiltInSubscriptionsFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetSelectedBuiltInSubscriptionsFunction( ++ const AdblockPrivateGetSelectedBuiltInSubscriptionsFunction&) = delete; ++ AdblockPrivateGetSelectedBuiltInSubscriptionsFunction& operator=( ++ const AdblockPrivateGetSelectedBuiltInSubscriptionsFunction&) = delete; ++}; ++ ++class AdblockPrivateAddCustomSubscriptionFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.addCustomSubscription", ++ ADBLOCKPRIVATE_ADDCUSTOMSUBSCRIPTION) ++ AdblockPrivateAddCustomSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateAddCustomSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateAddCustomSubscriptionFunction( ++ const AdblockPrivateAddCustomSubscriptionFunction&) = delete; ++ AdblockPrivateAddCustomSubscriptionFunction& operator=( ++ const AdblockPrivateAddCustomSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateRemoveCustomSubscriptionFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.removeCustomSubscription", ++ ADBLOCKPRIVATE_REMOVECUSTOMSUBSCRIPTION) ++ AdblockPrivateRemoveCustomSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateRemoveCustomSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateRemoveCustomSubscriptionFunction( ++ const AdblockPrivateRemoveCustomSubscriptionFunction&) = delete; ++ AdblockPrivateRemoveCustomSubscriptionFunction& operator=( ++ const AdblockPrivateRemoveCustomSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateGetCustomSubscriptionsFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getCustomSubscriptions", ++ ADBLOCKPRIVATE_GETCUSTOMSUBSCRIPTIONS) ++ AdblockPrivateGetCustomSubscriptionsFunction(); ++ ++ private: ++ ~AdblockPrivateGetCustomSubscriptionsFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetCustomSubscriptionsFunction( ++ const AdblockPrivateGetCustomSubscriptionsFunction&) = delete; ++ AdblockPrivateGetCustomSubscriptionsFunction& operator=( ++ const AdblockPrivateGetCustomSubscriptionsFunction&) = delete; ++}; ++ ++class AdblockPrivateInstallSubscriptionFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.installSubscription", ++ ADBLOCKPRIVATE_INSTALLSUBSCRIPTION) ++ AdblockPrivateInstallSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateInstallSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateInstallSubscriptionFunction( ++ const AdblockPrivateInstallSubscriptionFunction&) = delete; ++ AdblockPrivateInstallSubscriptionFunction& operator=( ++ const AdblockPrivateInstallSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateUninstallSubscriptionFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.uninstallSubscription", ++ ADBLOCKPRIVATE_UNINSTALLSUBSCRIPTION) ++ AdblockPrivateUninstallSubscriptionFunction(); ++ ++ private: ++ ~AdblockPrivateUninstallSubscriptionFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateUninstallSubscriptionFunction( ++ const AdblockPrivateUninstallSubscriptionFunction&) = delete; ++ AdblockPrivateUninstallSubscriptionFunction& operator=( ++ const AdblockPrivateUninstallSubscriptionFunction&) = delete; ++}; ++ ++class AdblockPrivateGetInstalledSubscriptionsFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getInstalledSubscriptions", ++ ADBLOCKPRIVATE_GETINSTALLEDSUBSCRIPTIONS) ++ AdblockPrivateGetInstalledSubscriptionsFunction(); ++ ++ private: ++ ~AdblockPrivateGetInstalledSubscriptionsFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetInstalledSubscriptionsFunction( ++ const AdblockPrivateGetInstalledSubscriptionsFunction&) = delete; ++ AdblockPrivateGetInstalledSubscriptionsFunction& operator=( ++ const AdblockPrivateGetInstalledSubscriptionsFunction&) = delete; ++}; ++ ++class AdblockPrivateAddAllowedDomainFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.addAllowedDomain", ++ ADBLOCKPRIVATE_ADDALLOWEDDOMAIN) ++ AdblockPrivateAddAllowedDomainFunction(); ++ ++ private: ++ ~AdblockPrivateAddAllowedDomainFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateAddAllowedDomainFunction( ++ const AdblockPrivateAddAllowedDomainFunction&) = delete; ++ AdblockPrivateAddAllowedDomainFunction& operator=( ++ const AdblockPrivateAddAllowedDomainFunction&) = delete; ++}; ++ ++class AdblockPrivateRemoveAllowedDomainFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.removeAllowedDomain", ++ ADBLOCKPRIVATE_REMOVEALLOWEDDOMAIN) ++ AdblockPrivateRemoveAllowedDomainFunction(); ++ ++ private: ++ ~AdblockPrivateRemoveAllowedDomainFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateRemoveAllowedDomainFunction( ++ const AdblockPrivateRemoveAllowedDomainFunction&) = delete; ++ AdblockPrivateRemoveAllowedDomainFunction& operator=( ++ const AdblockPrivateRemoveAllowedDomainFunction&) = delete; ++}; ++ ++class AdblockPrivateGetAllowedDomainsFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getAllowedDomains", ++ ADBLOCKPRIVATE_GETALLOWEDDOMAINS) ++ AdblockPrivateGetAllowedDomainsFunction(); ++ ++ private: ++ ~AdblockPrivateGetAllowedDomainsFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetAllowedDomainsFunction( ++ const AdblockPrivateGetAllowedDomainsFunction&) = delete; ++ AdblockPrivateGetAllowedDomainsFunction& operator=( ++ const AdblockPrivateGetAllowedDomainsFunction&) = delete; ++}; ++ ++class AdblockPrivateAddCustomFilterFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.addCustomFilter", ++ ADBLOCKPRIVATE_ADDCUSTOMFILTER) ++ AdblockPrivateAddCustomFilterFunction(); ++ ++ private: ++ ~AdblockPrivateAddCustomFilterFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateAddCustomFilterFunction( ++ const AdblockPrivateAddCustomFilterFunction&) = delete; ++ AdblockPrivateAddCustomFilterFunction& operator=( ++ const AdblockPrivateAddCustomFilterFunction&) = delete; ++}; ++ ++class AdblockPrivateRemoveCustomFilterFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.removeCustomFilter", ++ ADBLOCKPRIVATE_REMOVECUSTOMFILTER) ++ AdblockPrivateRemoveCustomFilterFunction(); ++ ++ private: ++ ~AdblockPrivateRemoveCustomFilterFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateRemoveCustomFilterFunction( ++ const AdblockPrivateRemoveCustomFilterFunction&) = delete; ++ AdblockPrivateRemoveCustomFilterFunction& operator=( ++ const AdblockPrivateRemoveCustomFilterFunction&) = delete; ++}; ++ ++class AdblockPrivateGetCustomFiltersFunction : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getCustomFilters", ++ ADBLOCKPRIVATE_GETCUSTOMFILTERS) ++ AdblockPrivateGetCustomFiltersFunction(); ++ ++ private: ++ ~AdblockPrivateGetCustomFiltersFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetCustomFiltersFunction( ++ const AdblockPrivateGetCustomFiltersFunction&) = delete; ++ AdblockPrivateGetCustomFiltersFunction& operator=( ++ const AdblockPrivateGetCustomFiltersFunction&) = delete; ++}; ++ ++class AdblockPrivateGetSessionAllowedAdsCountFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getSessionAllowedAdsCount", ++ ADBLOCKPRIVATE_GETSESSIONALLOWEDADSCOUNT) ++ AdblockPrivateGetSessionAllowedAdsCountFunction(); ++ ++ private: ++ ~AdblockPrivateGetSessionAllowedAdsCountFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetSessionAllowedAdsCountFunction( ++ const AdblockPrivateGetSessionAllowedAdsCountFunction&) = delete; ++ AdblockPrivateGetSessionAllowedAdsCountFunction& operator=( ++ const AdblockPrivateGetSessionAllowedAdsCountFunction&) = delete; ++}; ++ ++class AdblockPrivateGetSessionBlockedAdsCountFunction ++ : public ExtensionFunction { ++ public: ++ DECLARE_EXTENSION_FUNCTION("adblockPrivate.getSessionBlockedAdsCount", ++ ADBLOCKPRIVATE_GETSESSIONBLOCKEDADSCOUNT) ++ AdblockPrivateGetSessionBlockedAdsCountFunction(); ++ ++ private: ++ ~AdblockPrivateGetSessionBlockedAdsCountFunction() override; ++ ++ ResponseAction Run() override; ++ ++ AdblockPrivateGetSessionBlockedAdsCountFunction( ++ const AdblockPrivateGetSessionBlockedAdsCountFunction&) = delete; ++ AdblockPrivateGetSessionBlockedAdsCountFunction& operator=( ++ const AdblockPrivateGetSessionBlockedAdsCountFunction&) = delete; ++}; ++ ++} // namespace api ++ ++} // namespace extensions ++ ++#endif // CHROME_BROWSER_EXTENSIONS_API_ADBLOCK_PRIVATE_ADBLOCK_PRIVATE_API_H_ +diff --git a/chrome/browser/extensions/api/adblock_private/adblock_private_apitest.cc b/chrome/browser/extensions/api/adblock_private/adblock_private_apitest.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/extensions/api/adblock_private/adblock_private_apitest.cc +@@ -0,0 +1,717 @@ ++// This file is part of eyeo Chromium SDK, ++// Copyright (C) 2006-present eyeo GmbH ++// ++// eyeo Chromium SDK is free software: you can redistribute it and/or modify ++// it under the terms of the GNU General Public License version 3 as ++// published by the Free Software Foundation. ++// ++// eyeo Chromium SDK is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with eyeo Chromium SDK. If not, see . ++ ++#include ++#include ++#include ++ ++#include "chrome/browser/adblock/adblock_content_browser_client.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/extensions/extension_apitest.h" ++#include "chrome/common/extensions/api/adblock_private.h" ++#include "chrome/common/extensions/api/tabs.h" ++#include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_controller.h" ++#include "components/adblock/core/common/adblock_constants.h" ++#include "components/adblock/core/subscription/subscription_config.h" ++#include "content/public/test/browser_test.h" ++#include "extensions/browser/background_script_executor.h" ++#include "net/dns/mock_host_resolver.h" ++#include "net/test/embedded_test_server/embedded_test_server.h" ++#include "net/test/embedded_test_server/http_request.h" ++#include "net/test/embedded_test_server/http_response.h" ++#include "testing/gmock/include/gmock/gmock.h" ++#include "testing/gtest/include/gtest/gtest.h" ++ ++using testing::_; ++using testing::Mock; ++using testing::Return; ++ ++namespace extensions { ++ ++class AdblockPrivateApiTest : public ExtensionApiTest { ++ public: ++ AdblockPrivateApiTest() {} ++ ~AdblockPrivateApiTest() override = default; ++ AdblockPrivateApiTest(const AdblockPrivateApiTest&) = delete; ++ AdblockPrivateApiTest& operator=(const AdblockPrivateApiTest&) = delete; ++ ++ protected: ++ void SetUpOnMainThread() override { ++ ExtensionApiTest::SetUpOnMainThread(); ++ ++ // When any of that fails we need to update comment in adblock_private.idl ++ ASSERT_EQ(api::tabs::TAB_ID_NONE, -1); ++ ASSERT_EQ(SessionID::InvalidValue().id(), -1); ++ ++ adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser()->profile()) ++ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter); ++ ++ AdblockContentBrowserClient::ForceAdblockProxyForTesting(); ++ } ++ ++ bool RunTest(const std::string& subtest) { ++ const std::string page_url = "main.html?" + subtest; ++ return RunExtensionTest("adblock_private", ++ {.extension_url = page_url.c_str()}, ++ {.load_as_component = true}); ++ } ++ ++ bool RunTestWithParams(const std::string& subtest, ++ const std::map& params) { ++ if (params.empty()) { ++ return RunTest(subtest); ++ } ++ std::string subtest_with_params = subtest; ++ for (const auto& [key, value] : params) { ++ subtest_with_params += "&" + key + "=" + value; ++ } ++ return RunTest(subtest_with_params); ++ } ++ ++ bool RunTestWithServer(const std::string& subtest, ++ const std::string& subscription_path, ++ const std::string& subscription_filters) { ++ net::EmbeddedTestServer https_server{ ++ net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)}; ++ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); ++ https_server.RegisterRequestHandler(base::BindRepeating( ++ &AdblockPrivateApiTest::HandleSubscriptionUpdateRequest, ++ base::Unretained(this), subscription_path, subscription_filters)); ++ if (!https_server.Start()) { ++ return false; ++ } ++ const std::string subtest_with_params = ++ subtest + ++ "&subscription_url=" + https_server.GetURL(subscription_path).spec(); ++ return RunTest(subtest_with_params); ++ } ++ ++ std::unique_ptr ++ HandleSubscriptionUpdateRequest( ++ const std::string subscription_path, ++ const std::string subscription_filters, ++ const net::test_server::HttpRequest& request) { ++ static const char kSubscriptionHeader[] = ++ "[Adblock Plus 2.0]\n" ++ "! Checksum: X5A8vtJDBW2a9EgS9glqbg\n" ++ "! Version: 202202061935\n" ++ "! Last modified: 06 Feb 2022 19:35 UTC\n" ++ "! Expires: 1 days (update frequency)\n\n"; ++ ++ if (base::StartsWith(request.relative_url, subscription_path, ++ base::CompareCase::SENSITIVE)) { ++ auto http_response = ++ std::make_unique(); ++ http_response->set_code(net::HTTP_OK); ++ http_response->set_content(kSubscriptionHeader + subscription_filters); ++ http_response->set_content_type("text/plain"); ++ return std::move(http_response); ++ } ++ ++ // Unhandled requests result in the Embedded test server sending a 404. ++ return nullptr; ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, SetAndCheckEnabled) { ++ EXPECT_TRUE(RunTest("setEnabled_isEnabled")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, SetAndCheckAAEnabled) { ++ EXPECT_TRUE(RunTest("setAAEnabled_isAAEnabled")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, GetBuiltInSubscriptions) { ++ EXPECT_TRUE(RunTest("getBuiltInSubscriptions")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, SelectedSubscriptionsDataSchema) { ++ EXPECT_TRUE(RunTest("selectedSubscriptionsDataSchema")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, ++ SelectBuiltInSubscriptionsInvalidURL) { ++ EXPECT_TRUE(RunTest("selectBuiltInSubscriptionsInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, ++ SelectBuiltInSubscriptionsNotBuiltIn) { ++ EXPECT_TRUE(RunTest("selectBuiltInSubscriptionsNotBuiltIn")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, ++ UnselectBuiltInSubscriptionsInvalidURL) { ++ EXPECT_TRUE(RunTest("unselectBuiltInSubscriptionsInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, ++ UnselectBuiltInSubscriptionsNotBuiltIn) { ++ EXPECT_TRUE(RunTest("unselectBuiltInSubscriptionsNotBuiltIn")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, BuiltInSubscriptionsManagement) { ++ DCHECK(browser()->profile()); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser()->profile()); ++ auto selected = controller->GetSelectedBuiltInSubscriptions(); ++ const auto easylist = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "easylist.txt"); ++ }); ++ const auto exceptions = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "exceptionrules.txt"); ++ }); ++ const auto snippets = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "abp-filters-anti-cv.txt"); ++ }); ++ if (easylist == selected.end() || exceptions == selected.end() || ++ snippets == selected.end()) { ++ // Since default configuration has been changed let's skip this test ++ return; ++ } ++ const std::map params = { ++ {"easylist", (*easylist)->GetSourceUrl().spec()}, ++ {"exceptions", (*exceptions)->GetSourceUrl().spec()}, ++ {"snippets", (*snippets)->GetSourceUrl().spec()}}; ++ EXPECT_TRUE(RunTestWithParams("builtInSubscriptionsManagement", params)) ++ << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, ++ InstalledSubscriptionsDataSchema) { ++ EXPECT_TRUE(RunTest("installedSubscriptionsDataSchema")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, InstallSubscriptionInvalidURL) { ++ EXPECT_TRUE(RunTest("installSubscriptionInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, UninstallSubscriptionInvalidURL) { ++ EXPECT_TRUE(RunTest("uninstallSubscriptionInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, SubscriptionsManagement) { ++ DCHECK(browser()->profile()); ++ auto* controller = adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser()->profile()); ++ auto selected = controller->GetInstalledSubscriptions(); ++ const auto easylist = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "easylist.txt"); ++ }); ++ const auto exceptions = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "exceptionrules.txt"); ++ }); ++ const auto snippets = std::find_if( ++ selected.begin(), selected.end(), ++ [&](scoped_refptr subscription) { ++ return base::EndsWith(subscription->GetSourceUrl().path_piece(), ++ "abp-filters-anti-cv.txt"); ++ }); ++ if (easylist == selected.end() || exceptions == selected.end() || ++ snippets == selected.end()) { ++ // Since default configuration has been changed let's skip this test ++ return; ++ } ++ const std::map params = { ++ {"easylist", (*easylist)->GetSourceUrl().spec()}, ++ {"exceptions", (*exceptions)->GetSourceUrl().spec()}, ++ {"snippets", (*snippets)->GetSourceUrl().spec()}}; ++ EXPECT_TRUE(RunTestWithParams("subscriptionsManagement", params)) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, CustomSubscriptionInvalidURL) { ++ EXPECT_TRUE(RunTest("addCustomSubscriptionInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, RemoveSubscriptionInvalidURL) { ++ EXPECT_TRUE(RunTest("removeCustomSubscriptionInvalidURL")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, CustomSubscriptionsManagement) { ++ EXPECT_TRUE(RunTest("customSubscriptionsManagement")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, AllowedDomainsManagement) { ++ EXPECT_TRUE(RunTest("allowedDomainsManagement")) << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, AdBlockedEvents) { ++ std::string subscription_path = "/testeventssub.txt"; ++ std::string subscription_filters = "test1.png"; ++ ++ EXPECT_TRUE(RunTestWithServer("adBlockedEvents", subscription_path, ++ subscription_filters)) ++ << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, AdAllowedEvents) { ++ std::string subscription_path = "/testeventssub.txt"; ++ std::string subscription_filters = "test2.png\n@@test2.png"; ++ ++ EXPECT_TRUE(RunTestWithServer("adAllowedEvents", subscription_path, ++ subscription_filters)) ++ << message_; ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiTest, SessionStats) { ++ std::string subscription_path = "/teststatssub.txt"; ++ std::string subscription_filters = "test3.png\ntest4.png\n@@test4.png"; ++ ++ EXPECT_TRUE(RunTestWithServer("sessionStats", subscription_path, ++ subscription_filters)) ++ << message_; ++} ++ ++class AdblockPrivateApiBackgroundPageTest : public ExtensionApiTest { ++ public: ++ AdblockPrivateApiBackgroundPageTest() {} ++ ~AdblockPrivateApiBackgroundPageTest() override = default; ++ AdblockPrivateApiBackgroundPageTest( ++ const AdblockPrivateApiBackgroundPageTest&) = delete; ++ AdblockPrivateApiBackgroundPageTest& operator=( ++ const AdblockPrivateApiBackgroundPageTest&) = delete; ++ ++ protected: ++ void SetUpOnMainThread() override { ++ ExtensionApiTest::SetUpOnMainThread(); ++ ++ // Map example.com to localhost. ++ host_resolver()->AddRule("example.com", "127.0.0.1"); ++ ASSERT_TRUE(StartEmbeddedTestServer()); ++ adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser()->profile()) ++ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter); ++ } ++ ++ void ExecuteScript(const std::string& js_code) const { ++ content::WebContents* web_contents = ++ browser()->tab_strip_model()->GetActiveWebContents(); ++ ASSERT_TRUE(content::ExecJs(web_contents->GetPrimaryMainFrame(), js_code)); ++ } ++}; ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTest, PageAllowedEvents) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kSetListenersScript[] = R"( ++ var testData = {}; ++ testData.pageAllowedCount = 0; ++ chrome.adblockPrivate.onPageAllowed.addListener(function(e) { ++ if (!e.url.endsWith('test.html')) { ++ return; ++ } ++ testData.pageAllowedCount = testData.pageAllowedCount + 1; ++ }); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kReadCountersScript[] = R"( ++ window.domAutomationController.send(testData.pageAllowedCount.toString()); ++ )"; ++ ++ constexpr char kAllowDomainScript[] = R"( ++ chrome.adblockPrivate.addAllowedDomain('example.com'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ const GURL test_url = embedded_test_server()->GetURL( ++ "example.com", "/extensions/api_test/adblock_private/test.html"); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript); ++ ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ( ++ "0", ExecuteScriptInBackgroundPage(extension->id(), kReadCountersScript)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kAllowDomainScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ( ++ "1", ExecuteScriptInBackgroundPage(extension->id(), kReadCountersScript)); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTest, PageAllowedStats) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kReadAllowedStatsScript[] = R"( ++ chrome.adblockPrivate.getSessionAllowedAdsCount(function(sessionStats) { ++ let count = 0; ++ for (const entry of sessionStats) { ++ if (entry.url === 'adblock:custom') { ++ count = entry.count; ++ } ++ } ++ window.domAutomationController.send(count.toString()); ++ }); ++ )"; ++ ++ constexpr char kAllowDomainScript[] = R"( ++ chrome.adblockPrivate.addAllowedDomain('example.com'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ const GURL test_url = embedded_test_server()->GetURL( ++ "example.com", "/extensions/api_test/adblock_private/test.html"); ++ int initial_value = std::stoi( ++ ExecuteScriptInBackgroundPage(extension->id(), kReadAllowedStatsScript)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kAllowDomainScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ++ ASSERT_EQ(initial_value + 1, std::stoi(ExecuteScriptInBackgroundPage( ++ extension->id(), kReadAllowedStatsScript))); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTest, PopupEvents) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kSetListenersScript[] = R"( ++ var testData = {}; ++ testData.popupBlockedCount = 0; ++ testData.popupAllowedCount = 0; ++ chrome.adblockPrivate.onPopupAllowed.addListener(function(e, blocked) { ++ if (!e.url.endsWith('some-popup.html')) { ++ return; ++ } ++ testData.popupAllowedCount = testData.popupAllowedCount + 1; ++ }); ++ chrome.adblockPrivate.onPopupBlocked.addListener(function(e, blocked) { ++ if (!e.url.endsWith('some-popup.html')) { ++ return; ++ } ++ testData.popupBlockedCount = testData.popupBlockedCount + 1; ++ }); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kReadCountersScript[] = R"( ++ window.domAutomationController.send(testData.popupBlockedCount + ++ '-' + testData.popupAllowedCount); ++ )"; ++ ++ constexpr char kBlockPopupScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('some-popup.html^$popup'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kAllowPopupScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('@@some-popup.html^$popup'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ const GURL test_url = embedded_test_server()->GetURL( ++ "example.com", "/extensions/api_test/adblock_private/test.html"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript); ++ ASSERT_EQ("0-0", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kBlockPopupScript); ++ ExecuteScript("window.open('some-popup.html');"); ++ ASSERT_EQ("1-0", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kAllowPopupScript); ++ ExecuteScript("window.open('some-popup.html');"); ++ ASSERT_EQ("1-1", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++} ++ ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTest, PopupStats) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kReadAllowedStatsScript[] = R"( ++ chrome.adblockPrivate.getSessionAllowedAdsCount(function(sessionStats) { ++ let count = 0; ++ for (const entry of sessionStats) { ++ if (entry.url === 'adblock:custom') { ++ count = entry.count; ++ } ++ } ++ window.domAutomationController.send(count.toString()); ++ }); ++ )"; ++ ++ constexpr char kReadBlockedStatsScript[] = R"( ++ chrome.adblockPrivate.getSessionBlockedAdsCount(function(sessionStats) { ++ let count = 0; ++ for (const entry of sessionStats) { ++ if (entry.url === 'adblock:custom') { ++ count = entry.count; ++ } ++ } ++ window.domAutomationController.send(count.toString()); ++ }); ++ )"; ++ ++ constexpr char kBlockPopupScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('some-popup.html^$popup'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kAllowPopupScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('@@some-popup.html^$popup'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ const GURL test_url = embedded_test_server()->GetURL( ++ "example.com", "/extensions/api_test/adblock_private/test.html"); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ++ int initial_allowed_value = std::stoi( ++ ExecuteScriptInBackgroundPage(extension->id(), kReadAllowedStatsScript)); ++ int initial_blocked_value = std::stoi( ++ ExecuteScriptInBackgroundPage(extension->id(), kReadBlockedStatsScript)); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kBlockPopupScript); ++ ExecuteScript("window.open('some-popup.html');"); ++ ASSERT_EQ(initial_blocked_value + 1, ++ std::stoi(ExecuteScriptInBackgroundPage(extension->id(), ++ kReadBlockedStatsScript))); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kAllowPopupScript); ++ ExecuteScript("window.open('some-popup.html');"); ++ ASSERT_EQ(initial_allowed_value + 1, ++ std::stoi(ExecuteScriptInBackgroundPage(extension->id(), ++ kReadAllowedStatsScript))); ++} ++ ++class AdblockPrivateApiBackgroundPageTestWithRedirect ++ : public AdblockPrivateApiBackgroundPageTest { ++ public: ++ AdblockPrivateApiBackgroundPageTestWithRedirect() {} ++ ~AdblockPrivateApiBackgroundPageTestWithRedirect() override = default; ++ AdblockPrivateApiBackgroundPageTestWithRedirect( ++ const AdblockPrivateApiBackgroundPageTestWithRedirect&) = delete; ++ AdblockPrivateApiBackgroundPageTestWithRedirect& operator=( ++ const AdblockPrivateApiBackgroundPageTestWithRedirect&) = delete; ++ ++ protected: ++ void SetUpOnMainThread() override { ++ ExtensionApiTest::SetUpOnMainThread(); ++ ++ // Map domains to localhost. Add redirect handler. ++ host_resolver()->AddRule(before_redirect_domain, "127.0.0.1"); ++ host_resolver()->AddRule(after_redirect_domain, "127.0.0.1"); ++ embedded_test_server()->RegisterRequestHandler(base::BindRepeating( ++ &AdblockPrivateApiBackgroundPageTestWithRedirect::RequestHandler, ++ base::Unretained(this))); ++ ASSERT_TRUE(StartEmbeddedTestServer()); ++ adblock::AdblockControllerFactory::GetForBrowserContext( ++ browser()->profile()) ++ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter); ++ } ++ ++ std::unique_ptr RequestHandler( ++ const net::test_server::HttpRequest& request) { ++ if (base::EndsWith(request.relative_url, before_redirect_domain, ++ base::CompareCase::SENSITIVE)) { ++ std::unique_ptr http_response( ++ new net::test_server::BasicHttpResponse()); ++ http_response->set_code(net::HTTP_FOUND); ++ http_response->set_content("Redirecting..."); ++ http_response->set_content_type("text/plain"); ++ http_response->AddCustomHeader( ++ "Location", "http://" + after_redirect_domain + ":" + ++ base::NumberToString(embedded_test_server()->port()) + ++ request.relative_url.substr( ++ 0, request.relative_url.size() - ++ before_redirect_domain.size() - 1)); ++ return std::move(http_response); ++ } ++ if (base::EndsWith(request.relative_url, subresource_with_redirect, ++ base::CompareCase::SENSITIVE)) { ++ auto http_response = ++ std::make_unique(); ++ http_response->set_code(net::HTTP_OK); ++ // Create a sub resource url which causes redirection ++ const GURL url = embedded_test_server()->GetURL( ++ before_redirect_domain, "/image.png?" + before_redirect_domain); ++ std::string body = ""; ++ http_response->set_content(body); ++ http_response->set_content_type("text/html"); ++ return std::move(http_response); ++ } ++ ++ // Unhandled requests result in the Embedded test server sending a 404. ++ return nullptr; ++ } ++ ++ const std::string before_redirect_domain = "before-redirect.com"; ++ const std::string after_redirect_domain = "after-redirect.com"; ++ const std::string subresource_with_redirect = "subresource_with_redirect"; ++}; ++ ++// Test for DPD-1519 ++// This test verifies redirection of a main page ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTestWithRedirect, ++ PageAllowedEvents) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kSetListenersScript[] = R"( ++ var testData = {}; ++ testData.pageAllowedBeforeRedirectCount = 0; ++ testData.pageAllowedAfterRedirectCount = 0; ++ chrome.adblockPrivate.onPageAllowed.addListener(function(e) { ++ if (e.url.includes('before-redirect.com')) { ++ ++testData.pageAllowedBeforeRedirectCount; ++ } else if (e.url.includes('after-redirect.com')) { ++ ++testData.pageAllowedAfterRedirectCount; ++ } ++ }); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kReadCountersScript[] = R"( ++ window.domAutomationController.send( ++ testData.pageAllowedBeforeRedirectCount + '-' + ++ testData.pageAllowedAfterRedirectCount); ++ )"; ++ ++ constexpr char kAddAllowDomainScript[] = R"( ++ chrome.adblockPrivate.addAllowedDomain('after-redirect.com'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kRemoveAllowDomainScript[] = R"( ++ chrome.adblockPrivate.removeAllowedDomain('after-redirect.com'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kAddBlockDomainFilterScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('after-redirect.com'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ // Because RequestHandler handler sees just a 127.0.0.1 instead of ++ // a domain we are passing here source domain as a path in url. ++ const GURL test_url = embedded_test_server()->GetURL( ++ before_redirect_domain, "/" + before_redirect_domain); ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript); ++ ++ // No filter ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("0-0", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ // Just allow filter ++ ExecuteScriptInBackgroundPage(extension->id(), kAddAllowDomainScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("0-1", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ // Just block filter ++ ExecuteScriptInBackgroundPage(extension->id(), kAddBlockDomainFilterScript); ++ ExecuteScriptInBackgroundPage(extension->id(), kRemoveAllowDomainScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("0-1", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ // Allow and block filter ++ ExecuteScriptInBackgroundPage(extension->id(), kAddAllowDomainScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("0-2", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++} ++ ++// This test verifies redirection of a sub resource ++IN_PROC_BROWSER_TEST_F(AdblockPrivateApiBackgroundPageTestWithRedirect, ++ AdMatchedEvents) { ++ const Extension* extension = ++ LoadExtension(test_data_dir_.AppendASCII("adblock_private")); ++ ASSERT_TRUE(extension); ++ ++ constexpr char kSetListenersScript[] = R"( ++ var testData = {}; ++ testData.adBlockedCount = 0; ++ testData.adAllowedCount = 0; ++ chrome.adblockPrivate.onAdBlocked.addListener(function(e) { ++ if (e.url.includes('http://after-redirect.com')) { ++ ++testData.adBlockedCount; ++ } ++ }); ++ chrome.adblockPrivate.onAdAllowed.addListener(function(e) { ++ if (e.url.includes('http://after-redirect.com')) { ++ ++testData.adAllowedCount; ++ } ++ }); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kReadCountersScript[] = R"( ++ window.domAutomationController.send( ++ testData.adBlockedCount + '-' + testData.adAllowedCount); ++ )"; ++ ++ constexpr char kAddBlockingFilterScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('||after-redirect.com*/image.png'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ constexpr char kAddAllowingFilterScript[] = R"( ++ chrome.adblockPrivate.addCustomFilter('@@||after-redirect.com*/image.png'); ++ window.domAutomationController.send(''); ++ )"; ++ ++ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript); ++ ++ const GURL test_url = embedded_test_server()->GetURL( ++ after_redirect_domain, "/" + subresource_with_redirect); ++ ++ // No filter ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("0-0", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ // Just block filter ++ ExecuteScriptInBackgroundPage(extension->id(), kAddBlockingFilterScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("1-0", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++ ++ // Allow and block filter ++ ExecuteScriptInBackgroundPage(extension->id(), kAddAllowingFilterScript); ++ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); ++ ASSERT_EQ("1-1", ExecuteScriptInBackgroundPage(extension->id(), ++ kReadCountersScript)); ++} ++ ++} // namespace extensions +diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc +--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc ++++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc +@@ -2,6 +2,10 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. ++ + #include "chrome/browser/extensions/api/settings_private/prefs_util.h" + + #include +@@ -25,6 +29,7 @@ + #include "chrome/browser/safe_browsing/generated_safe_browsing_pref.h" + #include "chrome/common/chrome_features.h" + #include "chrome/common/pref_names.h" ++#include "components/adblock/core/common/adblock_prefs.h" + #include "components/autofill/core/common/autofill_prefs.h" + #include "components/autofill_assistant/browser/public/prefs.h" + #include "components/bookmarks/common/bookmark_pref_names.h" +@@ -172,6 +177,20 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { + return *s_allowlist; + s_allowlist = new PrefsUtil::TypedPrefMap(); + ++ // Adblock settings ++ (*s_allowlist)[adblock::prefs::kEnableAdblockLegacy] = ++ settings_api::PrefType::PREF_TYPE_BOOLEAN; ++ (*s_allowlist)[adblock::prefs::kEnableAcceptableAdsLegacy] = ++ settings_api::PrefType::PREF_TYPE_BOOLEAN; ++ (*s_allowlist)[adblock::prefs::kAdblockSubscriptionsLegacy] = ++ settings_api::PrefType::PREF_TYPE_LIST; ++ (*s_allowlist)[adblock::prefs::kAdblockCustomSubscriptionsLegacy] = ++ settings_api::PrefType::PREF_TYPE_LIST; ++ (*s_allowlist)[adblock::prefs::kAdblockAllowedDomainsLegacy] = ++ settings_api::PrefType::PREF_TYPE_LIST; ++ (*s_allowlist)[adblock::prefs::kAdblockCustomFiltersLegacy] = ++ settings_api::PrefType::PREF_TYPE_LIST; ++ + // Miscellaneous + (*s_allowlist)[::embedder_support::kAlternateErrorPagesEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; +diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc +--- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc ++++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc +@@ -1,6 +1,10 @@ + // Copyright 2014 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/browser/extensions/browser_context_keyed_service_factories.h" + +@@ -8,6 +12,7 @@ + #include "build/chromeos_buildflags.h" + #include "chrome/browser/extensions/activity_log/activity_log.h" + #include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h" ++#include "chrome/browser/extensions/api/adblock_private/adblock_private_api.h" + #include "chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h" + #include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h" + #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h" +@@ -73,6 +78,7 @@ namespace chrome_extensions { + void EnsureBrowserContextKeyedServiceFactoriesBuilt() { + extensions::ActivityLog::GetFactoryInstance(); + extensions::ActivityLogAPI::GetFactoryInstance(); ++ extensions::AdblockPrivateAPI::GetFactoryInstance(); + extensions::AutofillPrivateEventRouterFactory::GetInstance(); + extensions::BluetoothLowEnergyAPI::GetFactoryInstance(); + extensions::BookmarksAPI::GetFactoryInstance(); +diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc +--- a/chrome/browser/net/errorpage_browsertest.cc ++++ b/chrome/browser/net/errorpage_browsertest.cc +@@ -2,6 +2,10 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. ++ + #include + #include + #include +@@ -39,6 +43,7 @@ + #include "chrome/common/pref_names.h" + #include "chrome/test/base/in_process_browser_test.h" + #include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/adblock_switches.h" + #include "components/browsing_data/content/browsing_data_helper.h" + #include "components/embedder_support/switches.h" + #include "components/error_page/content/browser/net_error_auto_reloader.h" +@@ -637,6 +642,9 @@ class ErrorPageAutoReloadTest : public InProcessBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(embedder_support::kEnableAutoReload); ++ // The URLLoaderInterceptor is not resilient to the browser making ++ // adblock-related requests, they confuse this test. ++ command_line->AppendSwitch(adblock::switches::kDisableAdblock); + } + + void TearDownOnMainThread() override { url_loader_interceptor_.reset(); } +diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +--- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc ++++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +@@ -1,6 +1,10 @@ + // Copyright 2017 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include + #include +@@ -20,6 +24,7 @@ + #include "chrome/browser/ui/browser.h" + #include "chrome/test/base/in_process_browser_test.h" + #include "chrome/test/base/ui_test_utils.h" ++#include "components/adblock/core/features.h" + #include "components/heavy_ad_intervention/heavy_ad_features.h" + #include "components/page_load_metrics/browser/ads_page_load_metrics_test_waiter.h" + #include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h" +@@ -1464,7 +1469,7 @@ class AdsPageLoadMetricsObserverResourceBrowserTest + {heavy_ad_intervention::features::kHeavyAdIntervention, {}}, + {heavy_ad_intervention::features::kHeavyAdPrivacyMitigations, + {{"host-threshold", "3"}}}}, +- {}); ++ {adblock::kAdblockPlusFeature}); + } + + ~AdsPageLoadMetricsObserverResourceBrowserTest() override {} +diff --git a/chrome/browser/permissions/notifications_engagement_service_unittest.cc b/chrome/browser/permissions/notifications_engagement_service_unittest.cc +--- a/chrome/browser/permissions/notifications_engagement_service_unittest.cc ++++ b/chrome/browser/permissions/notifications_engagement_service_unittest.cc +@@ -129,8 +129,9 @@ TEST_F(NotificationsEngagementServiceTest, + notifications_engagement_setting.at(1).setting_value); + } + ++// TODO(atokodi) DPD-1495: Re enable when it gets fixed in the upstream + TEST_F(NotificationsEngagementServiceTest, +- RecordNotificationDisplayedAndInteraction) { ++ DISABLED_RecordNotificationDisplayedAndInteraction) { + GURL url1("https://www.google.com/"); + GURL url2("https://www.youtube.com/"); + GURL url3("https://www.permissions.site.com/"); +diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn +--- a/chrome/browser/preferences/BUILD.gn ++++ b/chrome/browser/preferences/BUILD.gn +@@ -1,6 +1,10 @@ + # Copyright 2019 The Chromium Authors + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. ++# ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file. ++ + + import("//build/config/android/rules.gni") + +@@ -32,6 +36,7 @@ android_library("java") { + java_cpp_strings("java_pref_names_srcjar") { + sources = [ + "//chrome/common/pref_names.cc", ++ "//components/adblock/core/common/adblock_prefs.cc", + "//components/autofill/core/common/autofill_prefs.cc", + "//components/autofill_assistant/browser/public/prefs.cc", + "//components/commerce/core/pref_names.cc", +diff --git a/chrome/browser/prefs/chrome_command_line_pref_store.cc b/chrome/browser/prefs/chrome_command_line_pref_store.cc +--- a/chrome/browser/prefs/chrome_command_line_pref_store.cc ++++ b/chrome/browser/prefs/chrome_command_line_pref_store.cc +@@ -1,6 +1,10 @@ + // Copyright 2012 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/browser/prefs/chrome_command_line_pref_store.h" + +@@ -21,6 +25,8 @@ + #include "build/chromeos_buildflags.h" + #include "chrome/common/chrome_switches.h" + #include "chrome/common/pref_names.h" ++#include "components/adblock/core/adblock_switches.h" ++#include "components/adblock/core/common/adblock_prefs.h" + #include "components/browser_sync/browser_sync_switches.h" + #include "components/language/core/browser/pref_names.h" + #include "components/proxy_config/proxy_config_dictionary.h" +diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc +--- a/chrome/browser/prefs/chrome_pref_service_factory.cc ++++ b/chrome/browser/prefs/chrome_pref_service_factory.cc +@@ -1,6 +1,10 @@ + // Copyright 2012 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/browser/prefs/chrome_pref_service_factory.h" + +@@ -38,6 +42,7 @@ + #include "chrome/grit/browser_resources.h" + #include "chrome/grit/chromium_strings.h" + #include "chrome/grit/generated_resources.h" ++#include "components/adblock/core/common/adblock_prefs.h" + #include "components/component_updater/pref_names.h" + #include "components/policy/core/browser/configuration_policy_pref_store.h" + #include "components/pref_registry/pref_registry_syncable.h" +@@ -193,6 +198,12 @@ const prefs::TrackedPreferenceMetadata kTrackedPrefs[] = { + {32, prefs::kMediaCdmOriginData, EnforcementLevel::ENFORCE_ON_LOAD, + PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL}, + #endif // BUILDFLAG(IS_WIN) ++ {100, adblock::prefs::kSubscriptionSignatures, ++ EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::SPLIT, ++ ValueType::IMPERSONAL}, ++ {101, adblock::prefs::kLastUsedSchemaVersion, ++ EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC, ++ ValueType::IMPERSONAL}, + + // See note at top, new items added here also need to be added to + // histograms.xml's TrackedPreference enum. +diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc ++++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +@@ -1,6 +1,10 @@ + // Copyright 2013 The Chromium Authors + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. ++// ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. + + #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" + +@@ -11,6 +15,13 @@ + #include "build/chromeos_buildflags.h" + #include "chrome/browser/accessibility/page_colors_factory.h" + #include "chrome/browser/accuracy_tips/accuracy_service_factory.h" ++#include "chrome/browser/adblock/adblock_controller_factory.h" ++#include "chrome/browser/adblock/adblock_telemetry_service_factory.h" ++#include "chrome/browser/adblock/resource_classification_runner_factory.h" ++#include "chrome/browser/adblock/session_stats_factory.h" ++#include "chrome/browser/adblock/sitekey_storage_factory.h" ++#include "chrome/browser/adblock/subscription_persistent_metadata_factory.h" ++#include "chrome/browser/adblock/subscription_service_factory.h" + #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" + #include "chrome/browser/autocomplete/in_memory_url_index_factory.h" + #include "chrome/browser/autocomplete/shortcuts_backend_factory.h" +@@ -139,6 +150,7 @@ + #include "services/network/public/cpp/features.h" + + #if BUILDFLAG(IS_ANDROID) ++#include "chrome/browser/android/adblock/adblock_jni_factory.h" + #include "chrome/browser/android/explore_sites/explore_sites_service_factory.h" + #include "chrome/browser/android/reading_list/reading_list_manager_factory.h" + #include "chrome/browser/android/reading_list/reading_list_notification_service_factory.h" +@@ -385,9 +397,17 @@ void ChromeBrowserMainExtraPartsProfiles:: + #if BUILDFLAG(ENABLE_SESSION_SERVICE) + ExitTypeServiceFactory::GetInstance(); + #endif ++ adblock::AdblockControllerFactory::GetInstance(); ++ adblock::AdblockTelemetryServiceFactory::GetInstance(); ++ adblock::ResourceClassificationRunnerFactory::GetInstance(); ++ adblock::SessionStatsFactory::GetInstance(); ++ adblock::SitekeyStorageFactory::GetInstance(); + #if BUILDFLAG(IS_ANDROID) ++ adblock::AdblockJNIFactory::GetInstance(); + explore_sites::ExploreSitesServiceFactory::GetInstance(); + #endif ++ adblock::SubscriptionPersistentMetadataFactory::GetInstance(); ++ adblock::SubscriptionServiceFactory::GetInstance(); + FaviconServiceFactory::GetInstance(); + feature_engagement::TrackerFactory::GetInstance(); + #if !BUILDFLAG(IS_ANDROID) +diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc +--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc ++++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc +@@ -2,6 +2,10 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + ++// This source code is a part of eyeo Chromium SDK. ++// Use of this source code is governed by the GPLv3 that can be found in the ++// components/adblock/LICENSE file. ++ + #include + + #include "base/ranges/algorithm.h" +@@ -441,7 +445,17 @@ IN_PROC_BROWSER_TEST_F(ProfileKeyedServiceBrowserTest, + "WebRtcEventLogManagerKeyedService", + "WebrtcAudioPrivateEventService", + "feedback::FeedbackUploaderChrome", +- "sct_reporting::Factory" ++ "sct_reporting::Factory", ++ ++ // eyeo Chromium SDK services: ++ "AdblockController", ++ "AdblockPrivateAPI", ++ "AdblockSubscriptionPersistentMetadata", ++ "AdblockSubscriptionService", ++ "AdblockTelemetryService", ++ "ResourceClassificationRunner", ++ "SessionStats", ++ "SitekeyStorage", + }; + // clang-format on + +@@ -742,7 +756,17 @@ IN_PROC_BROWSER_TEST_F(ProfileKeyedServiceBrowserTest, + "WebRtcEventLogManagerKeyedService", + "WebrtcAudioPrivateEventService", + "feedback::FeedbackUploaderChrome", +- "sct_reporting::Factory" ++ "sct_reporting::Factory", ++ ++ // eyeo Chromium SDK services: ++ "AdblockController", ++ "AdblockPrivateAPI", ++ "AdblockSubscriptionPersistentMetadata", ++ "AdblockSubscriptionService", ++ "AdblockTelemetryService", ++ "ResourceClassificationRunner", ++ "SessionStats", ++ "SitekeyStorage", + }; + // clang-format on + +diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn +--- a/chrome/browser/resources/settings/BUILD.gn ++++ b/chrome/browser/resources/settings/BUILD.gn +@@ -2,6 +2,10 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + ++# This source code is a part of eyeo Chromium SDK. ++# Use of this source code is governed by the GPLv3 that can be found in the ++# components/adblock/LICENSE file. ++ + import("//build/config/chromeos/ui_mode.gni") + import("//chrome/browser/resources/tools/build_webui.gni") + import("//chrome/common/features.gni") +@@ -107,6 +111,7 @@ build_webui("build") { + "a11y_page/a11y_page.ts", + "a11y_page/live_caption_section.ts", + "about_page/about_page.ts", ++ "adblock_page/adblock_page.ts", + "appearance_page/appearance_fonts_page.ts", + "appearance_page/appearance_page.ts", + "appearance_page/home_url_input.ts", +diff --git a/chrome/browser/resources/settings/adblock_page/adblock_page.html b/chrome/browser/resources/settings/adblock_page/adblock_page.html +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/resources/settings/adblock_page/adblock_page.html +@@ -0,0 +1,186 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++
++ ++
++ Recommended Subscriptions ++
++
++ ++
++ ++
++
++ ++
++
++
++
++ ++
++ Allowed Domains ++
++
++ ++
++ ++
++
++ ++
++
++ ++ ++ Add ++ ++ ++
++
++
++
++
++
++ ++
++ Custom Subscriptions ++
++
++ ++
++ ++
++
++ ++
++
++ ++ ++ Add ++ ++ ++
++
++
++
++
++
++ ++
++ Custom Filters ++
++
++ ++
++ ++
++
++ ++
++
++ ++ ++ Add ++ ++ ++
++
++
++
++
++ ++
+diff --git a/chrome/browser/resources/settings/adblock_page/adblock_page.ts b/chrome/browser/resources/settings/adblock_page/adblock_page.ts +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/resources/settings/adblock_page/adblock_page.ts +@@ -0,0 +1,317 @@ ++/* ++ * This file is part of eyeo Chromium SDK, ++ * Copyright (C) 2006-present eyeo GmbH ++ * ++ * eyeo Chromium SDK is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 3 as ++ * published by the Free Software Foundation. ++ * ++ * eyeo Chromium SDK is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with eyeo Chromium SDK. If not, see . ++ */ ++import 'chrome://resources/cr_elements/cr_button/cr_button.js'; ++import 'chrome://resources/cr_elements/cr_shared_style.css.js'; ++import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; ++import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; ++import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; ++import '../controls/controlled_button.js'; ++import '../controls/settings_toggle_button.js'; ++import '../settings_shared.css.js'; ++ ++ ++import { I18nMixin } from 'chrome://resources/cr_elements/i18n_mixin.js'; ++import { BaseMixin } from '../base_mixin.js'; ++import { html, PolymerElement } from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; ++import { PrefsMixin } from '../prefs/prefs_mixin.js'; ++import { CrSettingsPrefs } from '../prefs/prefs_types.js'; ++import { CrCheckboxElement } from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; ++import { getTemplate } from './adblock_page.html.js'; ++ ++const SettingsAdblockPageElementBase = ++ I18nMixin(PrefsMixin(BaseMixin((PolymerElement)))); ++ ++export class SettingsAdblockPageElement extends ++ SettingsAdblockPageElementBase { ++ static get is() { ++ return 'settings-adblock-page'; ++ } ++ ++ static get template() { ++ return getTemplate(); ++ } ++ ++ private syncSubscriptions() { ++ let prefSubscriptions = this.getPref("adblock.subscriptions").value; ++ this.subscriptions.forEach((subscription, i) => { ++ if (prefSubscriptions.includes(subscription['url'])) { ++ this.set("subscriptions." + i.toString() + ".enabled", true) ++ } else { ++ this.set("subscriptions." + i.toString() + ".enabled", false) ++ } ++ }) ++ } ++ ++ private syncCustomSubscriptions() { ++ let prefCustomSubscriptions = this.getPref("adblock.custom_subscriptions").value; ++ this.customSubscriptions = []; ++ prefCustomSubscriptions.forEach((subscription: string) => { ++ this.customSubscriptions.push(subscription); ++ }) ++ } ++ ++ private syncCustomFilters() { ++ let prefCustomFilters = this.getPref("adblock.custom_filters").value; ++ this.customFilters = []; ++ prefCustomFilters.forEach((filter: string) => { ++ this.customFilters.push(filter); ++ }) ++ } ++ ++ private syncAllowedDomains() { ++ let prefAllowedDomains = this.getPref("adblock.allowed_domains").value; ++ this.allowedDomains = []; ++ prefAllowedDomains.forEach((subscription: string) => { ++ this.allowedDomains.push(subscription); ++ }) ++ } ++ ++ public override ready() { ++ super.ready(); ++ // when prefs are ready ++ CrSettingsPrefs.initialized.then(() => { ++ this.syncSubscriptions(); ++ this.syncCustomSubscriptions(); ++ this.syncCustomFilters(); ++ this.syncAllowedDomains(); ++ }); ++ } ++ ++ // input fields updated by html ++ public customSubscriptionInput: string; ++ public customFilterInput: string; ++ public allowedDomainInput: string; ++ ++ // models that will fill templates lists in html ++ public customSubscriptions: Array = []; ++ public customFilters: Array = []; ++ public allowedDomains: Array = []; ++ public subscriptions = [ ++ { ++ title: "ABPindo+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/abpindo+easylist.txt" ++ }, ++ { ++ title: "ABPVN List+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/abpvn+easylist.txt" ++ }, ++ { ++ title: "Bulgarian list+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/bulgarian_list+easylist.txt" ++ }, ++ { ++ title: "Dandelion Sprout's Nordic Filters+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/dandelion_sprouts_nordic_filters+easylist.txt" ++ }, ++ { ++ title: "EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylist.txt" ++ }, ++ { ++ title: "EasyList China+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt" ++ }, ++ { ++ title: "EasyList Czech and Slovak+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistczechslovak+easylist.txt" ++ }, ++ { ++ title: "EasyList Dutch+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistdutch+easylist.txt" ++ }, ++ { ++ title: "EasyList Germany+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt" ++ }, ++ { ++ title: "EasyList Hebrew+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/israellist+easylist.txt" ++ }, ++ { ++ title: "EasyList Italy+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistitaly+easylist.txt" ++ }, ++ { ++ title: "EasyList Lithuania+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistlithuania+easylist.txt" ++ }, ++ { ++ title: "EasyList Polish+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistpolish+easylist.txt" ++ }, ++ { ++ title: "EasyList Portuguese+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistportuguese+easylist.txt" ++ }, ++ { ++ title: "EasyList Spanish+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easylistspanish+easylist.txt" ++ }, ++ { ++ title: "IndianList+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/indianlist+easylist.txt" ++ }, ++ { ++ title: "KoreanList+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/koreanlist+easylist.txt" ++ }, ++ { ++ title: "Latvian List+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/latvianlist+easylist.txt" ++ }, ++ { ++ title: "Liste AR+Liste FR+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/liste_ar+liste_fr+easylist.txt" ++ }, ++ { ++ title: "Liste FR+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/liste_fr+easylist.txt" ++ }, ++ { ++ title: "ROList+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/rolist+easylist.txt" ++ }, ++ { ++ title: "RuAdList+EasyList", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt" ++ }, ++ { ++ title: "ABP filters", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/abp-filters-anti-cv.txt" ++ }, ++ { ++ title: "I don't care about cookies", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/i_dont_care_about_cookies.txt" ++ }, ++ { ++ title: "Fanboy's Notifications Blocking List", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/fanboy-notifications.txt" ++ }, ++ { ++ title: "EasyPrivacy", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/easyprivacy.txt" ++ }, ++ { ++ title: "Fanboy's Social Blocking List", ++ enabled: false, ++ url: "https://easylist-downloads.adblockplus.org/fanboy-social.txt" ++ } ++ ]; ++ ++ private cleanUrl(url: string) : string { ++ let cleanedUrl : string = ""; ++ try { ++ cleanedUrl = new URL(url).host; ++ } catch (err) { ++ try { ++ // one last try by adding schema ++ cleanedUrl = new URL("https://" + url).host; ++ } ++ catch (err) { ++ console.log("malformed url " + url); ++ } ++ } ++ return cleanedUrl; ++ } ++ ++ private selectRecommendedSubscription(e: Event) { ++ const url = ((e.target as CrCheckboxElement).id); ++ const enabled = ((e.target as CrCheckboxElement).checked); ++ if (enabled) { ++ this.appendPrefListItem("adblock.subscriptions", url); ++ } else { ++ this.deletePrefListItem("adblock.subscriptions", url); ++ } ++ } ++ ++ private removeCustomFilter(e: Event) { ++ const filter = ((e.target as HTMLElement).id); ++ this.deletePrefListItem("adblock.custom_filters", filter); ++ const i = this.customFilters.indexOf(filter); ++ this.splice('customFilters', i, 1); ++ } ++ ++ private addCustomFilter() { ++ if (this.customFilterInput == undefined) return; ++ this.appendPrefListItem("adblock.custom_filters", this.customFilterInput); ++ this.push('customFilters', this.customFilterInput); ++ } ++ ++ private removeAllowedDomain(e: Event) { ++ const allowedDomain = ((e.target as HTMLElement).id); ++ this.deletePrefListItem("adblock.allowed_domains", allowedDomain); ++ const i = this.allowedDomains.indexOf(allowedDomain); ++ this.splice('allowedDomains', i, 1); ++ } ++ ++ private addAllowedDomain() { ++ if (this.allowedDomainInput == undefined) return; ++ const cleanedUrl = this.cleanUrl(this.allowedDomainInput); ++ if (cleanedUrl == "") return; ++ this.appendPrefListItem("adblock.allowed_domains", cleanedUrl); ++ this.push('allowedDomains', cleanedUrl); ++ } ++ ++ private removeCustomSubscription(e: Event) { ++ const subscription = ((e.target as HTMLElement).id); ++ this.deletePrefListItem("adblock.custom_subscriptions", subscription); ++ const i = this.customSubscriptions.indexOf(subscription); ++ this.splice('customSubscriptions', i, 1); ++ } ++ ++ private addCustomSubscription() { ++ if (this.customSubscriptionInput == undefined) return; ++ this.appendPrefListItem("adblock.custom_subscriptions", this.customSubscriptionInput); ++ this.push('customSubscriptions', this.customSubscriptionInput); ++ } ++} ++ ++ ++declare global { ++ interface HTMLElementTagNameMap { ++ 'settings-adblock-page': SettingsAdblockPageElement; ++ } ++} ++ ++customElements.define( ++ SettingsAdblockPageElement.is, SettingsAdblockPageElement); +diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html +--- a/chrome/browser/resources/settings/basic_page/basic_page.html ++++ b/chrome/browser/resources/settings/basic_page/basic_page.html +@@ -24,6 +24,13 @@ + + + ++ +