From: AUTOMATED Date: Tue, 7 Feb 2023 11:32:19 +0000 Subject: Diff from 110.0.5481.50 --- 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 | 363 + .../adblock/adblock_content_browser_client.h | 110 + ...lock_content_browser_client_browsertest.cc | 122 + ...adblock_content_browser_client_unittest.cc | 197 + .../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 + ...ck_filtering_configurations_browsertest.cc | 355 + ...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 | 197 + .../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 + ...browser_context_keyed_service_factories.cc | 6 + .../api/settings_private/prefs_util.cc | 19 + ...browser_context_keyed_service_factories.cc | 4 + 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 | 24 +- chrome/browser/resources/settings/BUILD.gn | 5 + .../settings/adblock_page/adblock_page.html | 186 + .../settings/adblock_page/adblock_page.ts | 320 + .../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/router.ts | 5 + chrome/browser/resources/settings/settings.ts | 5 + .../settings/settings_menu/settings_menu.html | 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 | 25 + chrome/test/base/chrome_test_launcher.cc | 7 +- chrome/test/base/in_process_browser_test.cc | 17 +- .../filterlist_that_allows_resource.txt | 7 + .../filterlist_that_blocks_resource.txt | 6 + .../filterlist_that_hides_resource.txt | 6 + 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 | 550 + components/adblock/LICENSE | 674 + components/adblock/README.md | 80 + components/adblock/android/BUILD.gn | 146 + components/adblock/android/README.md | 13 + .../adblock/android/adblock_strings.grd | 222 + .../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 | 140 + .../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 | 13 + .../translations/adblock_strings_ar.xtb | 13 + .../translations/adblock_strings_as.xtb | 4 + .../translations/adblock_strings_az.xtb | 4 + .../translations/adblock_strings_be.xtb | 4 + .../translations/adblock_strings_bg.xtb | 16 + .../translations/adblock_strings_bn.xtb | 13 + .../translations/adblock_strings_bs.xtb | 13 + .../translations/adblock_strings_ca.xtb | 13 + .../translations/adblock_strings_cs.xtb | 13 + .../translations/adblock_strings_da.xtb | 13 + .../translations/adblock_strings_de.xtb | 13 + .../translations/adblock_strings_el.xtb | 13 + .../translations/adblock_strings_en-GB.xtb | 13 + .../translations/adblock_strings_es-419.xtb | 13 + .../translations/adblock_strings_es.xtb | 13 + .../translations/adblock_strings_et.xtb | 13 + .../translations/adblock_strings_eu.xtb | 4 + .../translations/adblock_strings_fa.xtb | 13 + .../translations/adblock_strings_fi.xtb | 13 + .../translations/adblock_strings_fil.xtb | 13 + .../translations/adblock_strings_fr-CA.xtb | 13 + .../translations/adblock_strings_fr.xtb | 13 + .../translations/adblock_strings_gl.xtb | 4 + .../translations/adblock_strings_gu.xtb | 4 + .../translations/adblock_strings_hi.xtb | 13 + .../translations/adblock_strings_hr.xtb | 13 + .../translations/adblock_strings_hu.xtb | 13 + .../translations/adblock_strings_hy.xtb | 4 + .../translations/adblock_strings_id.xtb | 13 + .../translations/adblock_strings_is.xtb | 4 + .../translations/adblock_strings_it.xtb | 13 + .../translations/adblock_strings_iw.xtb | 13 + .../translations/adblock_strings_ja.xtb | 13 + .../translations/adblock_strings_ka.xtb | 4 + .../translations/adblock_strings_kk.xtb | 13 + .../translations/adblock_strings_km.xtb | 13 + .../translations/adblock_strings_kn.xtb | 4 + .../translations/adblock_strings_ko.xtb | 13 + .../translations/adblock_strings_ky.xtb | 4 + .../translations/adblock_strings_lo.xtb | 4 + .../translations/adblock_strings_lt.xtb | 13 + .../translations/adblock_strings_lv.xtb | 13 + .../translations/adblock_strings_mk.xtb | 13 + .../translations/adblock_strings_ml.xtb | 4 + .../translations/adblock_strings_mn.xtb | 4 + .../translations/adblock_strings_mr.xtb | 4 + .../translations/adblock_strings_ms.xtb | 13 + .../translations/adblock_strings_my.xtb | 13 + .../translations/adblock_strings_ne.xtb | 4 + .../translations/adblock_strings_nl.xtb | 13 + .../translations/adblock_strings_no.xtb | 4 + .../translations/adblock_strings_or.xtb | 4 + .../translations/adblock_strings_pa.xtb | 4 + .../translations/adblock_strings_pl.xtb | 13 + .../translations/adblock_strings_pt-BR.xtb | 13 + .../translations/adblock_strings_pt-PT.xtb | 13 + .../translations/adblock_strings_ro.xtb | 13 + .../translations/adblock_strings_ru.xtb | 13 + .../translations/adblock_strings_si.xtb | 4 + .../translations/adblock_strings_sk.xtb | 13 + .../translations/adblock_strings_sl.xtb | 13 + .../translations/adblock_strings_sq.xtb | 4 + .../translations/adblock_strings_sr-Latn.xtb | 4 + .../translations/adblock_strings_sr.xtb | 13 + .../translations/adblock_strings_sv.xtb | 13 + .../translations/adblock_strings_sw.xtb | 13 + .../translations/adblock_strings_ta.xtb | 4 + .../translations/adblock_strings_te.xtb | 4 + .../translations/adblock_strings_th.xtb | 13 + .../translations/adblock_strings_tr.xtb | 13 + .../translations/adblock_strings_uk.xtb | 13 + .../translations/adblock_strings_ur.xtb | 13 + .../translations/adblock_strings_uz.xtb | 4 + .../translations/adblock_strings_vi.xtb | 13 + .../translations/adblock_strings_zh-CN.xtb | 13 + .../translations/adblock_strings_zh-HK.xtb | 4 + .../translations/adblock_strings_zh-TW.xtb | 13 + .../translations/adblock_strings_zu.xtb | 4 + components/adblock/content/BUILD.gn | 22 + components/adblock/content/browser/BUILD.gn | 121 + .../content/browser/adblock_filter_match.h | 30 + .../browser/adblock_url_loader_factory.cc | 679 + .../browser/adblock_url_loader_factory.h | 91 + .../adblock_url_loader_factory_for_test.cc | 194 + .../adblock_url_loader_factory_for_test.h | 73 + .../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 | 303 + .../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 | 106 + .../resource_classification_runner_impl.cc | 425 + .../resource_classification_runner_impl.h | 154 + .../content/browser/session_stats_impl.cc | 86 + .../content/browser/session_stats_impl.h | 69 + .../test/adblock_url_loader_factory_test.cc | 334 + .../test/adblock_webcontents_observer_test.cc | 159 + ...tent_security_policy_injector_impl_test.cc | 177 + .../browser/test/element_hider_impl_test.cc | 347 + .../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 | 49 + .../mock_resource_classification_runner.h | 97 + ...esource_classification_runner_impl_test.cc | 387 + .../browser/test/session_stats_impl_test.cc | 91 + 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 | 336 + .../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 | 296 + .../classifier/resource_classifier_impl.h | 59 + .../test/mock_resource_classifier.cc | 26 + .../test/mock_resource_classifier.h | 60 + .../test/resource_classifier_impl_test.cc | 504 + .../test/resource_classifier_perftest.cc | 229 + 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 | 192 + components/adblock/core/converter/metadata.h | 73 + .../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 | 2240 + .../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 | 128 + .../core/subscription/domain_splitter.cc | 45 + .../core/subscription/domain_splitter.h | 45 + .../filtering_configuration_maintainer.h | 52 + ...filtering_configuration_maintainer_impl.cc | 480 + .../filtering_configuration_maintainer_impl.h | 120 + .../subscription/installed_subscription.cc | 42 + .../subscription/installed_subscription.h | 138 + .../installed_subscription_impl.cc | 644 + .../installed_subscription_impl.h | 174 + .../ongoing_subscription_request.h | 50 + .../ongoing_subscription_request_impl.cc | 171 + .../ongoing_subscription_request_impl.h | 67 + .../preloaded_subscription_provider.h | 56 + .../preloaded_subscription_provider_impl.cc | 120 + .../preloaded_subscription_provider_impl.h | 52 + .../adblock/core/subscription/subscription.cc | 24 + .../adblock/core/subscription/subscription.h | 76 + .../subscription/subscription_collection.h | 95 + .../subscription_collection_impl.cc | 432 + .../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 | 228 + .../subscription_persistent_storage_impl.h | 79 + .../core/subscription/subscription_service.h | 74 + .../subscription/subscription_service_impl.cc | 145 + .../subscription/subscription_service_impl.h | 90 + .../core/subscription/subscription_updater.h | 35 + .../subscription/subscription_updater_impl.cc | 65 + .../subscription/subscription_updater_impl.h | 52 + .../subscription/subscription_validator.h | 59 + .../subscription_validator_impl.cc | 146 + .../subscription_validator_impl.h | 52 + ...ring_configuration_maintainer_impl_test.cc | 824 + .../test/installed_subscription_impl_test.cc | 74 + .../mock_filtering_configuration_mainainer.cc | 28 + .../mock_filtering_configuration_mainainer.h | 45 + .../test/mock_installed_subscription.cc | 26 + .../test/mock_installed_subscription.h | 102 + .../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 | 65 + .../test/mock_subscription_updater.cc | 25 + .../test/mock_subscription_updater.h | 38 + .../ongoing_subscription_request_impl_test.cc | 287 + ...eloaded_subscription_provider_impl_test.cc | 149 + .../test/subscription_collection_impl_test.cc | 1174 + .../test/subscription_downloader_impl_test.cc | 592 + ...scription_persistent_metadata_impl_test.cc | 213 + ...bscription_persistent_storage_impl_test.cc | 334 + .../test/subscription_service_impl_test.cc | 246 + .../test/subscription_updater_impl_test.cc | 98 + .../test/subscription_validator_impl_test.cc | 252 + .../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 | 268 + 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 | 2520 + components/resources/adblocking/easylist.txt | 15073 +++++ components/resources/adblocking/elemhide.js | 43 + .../adblocking/elemhide_for_selector.jst | 53 + .../resources/adblocking/elemhideemu.jst | 1436 + .../resources/adblocking/exceptionrules.txt | 6036 ++ 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 | 668 + tools/perf/page_sets/eyeo_page_set.py | 976 + 512 files changed, 148138 insertions(+), 23 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_filtering_configurations_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/filterlist_that_allows_resource.txt create mode 100644 chrome/test/data/adblock/filterlist_that_blocks_resource.txt create mode 100644 chrome/test/data/adblock/filterlist_that_hides_resource.txt 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/README.md 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_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_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/filtering_configuration_maintainer.h create mode 100644 components/adblock/core/subscription/filtering_configuration_maintainer_impl.cc create mode 100644 components/adblock/core/subscription/filtering_configuration_maintainer_impl.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.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/filtering_configuration_maintainer_impl_test.cc create mode 100644 components/adblock/core/subscription/test/installed_subscription_impl_test.cc create mode 100644 components/adblock/core/subscription/test/mock_filtering_configuration_mainainer.cc create mode 100644 components/adblock/core/subscription/test/mock_filtering_configuration_mainainer.h 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 @@ -169,6 +169,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. @@ -287,6 +291,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', @@ -476,6 +482,11 @@ vars = { # and whatever else without interference from each other. 'ffmpeg_revision': 'a249b21db6516234e5456716ae074fbb00176b3f', + # 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': '2948540a20cbb5b2192119f791b04dd62ca7af1c', @@ -775,6 +786,10 @@ deps = { 'condition': 'checkout_android and checkout_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' + '@' + 'a21816a490b5ed39b53b42b9ac3b60711cc7955d', }, @@ -924,6 +939,13 @@ deps = { 'dep_type': 'cipd', }, + 'src/tools/perf/eyeo_data': { + 'condition': + 'checkout_eyeo_wpr_archives', + 'url': + Var('eyeo_distpartners_gitlab') + '/web-page-recordings.git@11d94fc3155d73236fc820dc12da856c06e5ff06', + }, + '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") @@ -279,6 +283,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", @@ -495,6 +500,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/background_task_scheduler:background_task_scheduler_java", @@ -1601,6 +1607,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/background_task_scheduler:background_task_scheduler_java", @@ -4144,6 +4151,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/digital_asset_links/android:jni_headers", "//components/image_fetcher:jni_headers", "//components/media_router/browser/android:jni_headers", 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" @@ -1708,7 +1713,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") @@ -151,6 +154,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", @@ -2037,6 +2060,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", @@ -2529,6 +2553,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", @@ -3234,6 +3262,7 @@ static_library("browser") { "webauthn/android/webauthn_request_delegate_android.cc", "webauthn/android/webauthn_request_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,363 @@ +/* + * 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 "base/ranges/algorithm.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/configuration/filtering_configuration.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) { + // Filtering may be needed if there's at least one enabled + // FilteringConfiguration. + return base::ranges::any_of( + adblock::SubscriptionServiceFactory::GetForBrowserContext(profile) + ->GetInstalledFilteringConfigurations(), + &adblock::FilteringConfiguration::IsEnabled); + } + } + 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), + content::GlobalRenderFrameHostId(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), + content::GlobalRenderFrameHostId(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()); + + GURL popup_url(target_url); + web_contents->GetPrimaryMainFrame()->GetProcess()->FilterURL(false, + &popup_url); + auto* classification_runner = + adblock::ResourceClassificationRunnerFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + const auto popup_blocking_decision = + classification_runner->ShouldBlockPopup( + subscription_service->GetCurrentSnapshot(), popup_url, + opener_top_level_frame_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); + auto* classification_runner = + adblock::ResourceClassificationRunnerFactory::GetForBrowserContext( + browser_context); + classification_runner->CheckRequestFilterMatchForWebSocket( + subscription_service->GetCurrentSnapshot(), 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,197 @@ +/* + * 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/gmock_move_support.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 { + +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())); + } + + MockSubscriptionService* subscription_service_; + MockResourceClassificationRunner* resource_classification_runner_; +}; + +TEST_F(AdblockContentBrowserClientUnitTest, + WillInterceptWebSocketWhenFilteringEnabled) { + AdblockContentBrowserClient content_client; + subscription_service_->WillRequireFiltering(true); + EXPECT_TRUE(content_client.WillInterceptWebSocket(main_rfh())); +} + +TEST_F(AdblockContentBrowserClientUnitTest, + WillNotInterceptWebSocketWhenFilteringDisabled) { + AdblockContentBrowserClient content_client; + subscription_service_->WillRequireFiltering(false); + EXPECT_FALSE(content_client.WillInterceptWebSocket(main_rfh())); +} + +TEST_F(AdblockContentBrowserClientUnitTest, + RenderFrameHostDiesBeforeClassificationFinished) { + const auto kSocketUrl = GURL("wss://domain.com/test"); + subscription_service_->WillRequireFiltering(true); + EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { + SubscriptionService::Snapshot snapshot; + snapshot.push_back(std::make_unique()); + return snapshot; + }); + CheckFilterMatchCallback classification_callback; + EXPECT_CALL(*resource_classification_runner_, + CheckRequestFilterMatchForWebSocket(_, kSocketUrl, + main_rfh()->GetGlobalId(), _)) + .WillOnce(MoveArg<3>(&classification_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) { + subscription_service_->WillRequireFiltering(true); + const auto kSocketUrl = GURL("wss://domain.com/test"); + EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { + SubscriptionService::Snapshot snapshot; + snapshot.push_back(std::make_unique()); + return snapshot; + }); + CheckFilterMatchCallback classification_callback; + EXPECT_CALL(*resource_classification_runner_, + CheckRequestFilterMatchForWebSocket(_, kSocketUrl, + main_rfh()->GetGlobalId(), _)) + .WillOnce(MoveArg<3>(&classification_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) { + subscription_service_->WillRequireFiltering(true); + const auto kSocketUrl = GURL("wss://domain.com/test"); + EXPECT_CALL(*subscription_service_, GetCurrentSnapshot()).WillOnce([]() { + SubscriptionService::Snapshot snapshot; + snapshot.push_back(std::make_unique()); + return snapshot; + }); + CheckFilterMatchCallback classification_callback; + EXPECT_CALL(*resource_classification_runner_, + CheckRequestFilterMatchForWebSocket(_, kSocketUrl, + main_rfh()->GetGlobalId(), _)) + .WillOnce(MoveArg<3>(&classification_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_filtering_configurations_browsertest.cc b/chrome/browser/adblock/adblock_filtering_configurations_browsertest.cc new file mode 100644 --- /dev/null +++ b/chrome/browser/adblock/adblock_filtering_configurations_browsertest.cc @@ -0,0 +1,355 @@ +/* + * 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 "base/ranges/algorithm.h" +#include "base/run_loop.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/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/configuration/filtering_configuration.h" +#include "components/adblock/core/configuration/persistent_filtering_configuration.h" +#include "components/adblock/core/subscription/subscription_service.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 "gmock/gmock.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "url/gurl.h" + +namespace adblock { + +class SubscriptionInstalledWaiter + : public SubscriptionService::SubscriptionObserver { + public: + explicit SubscriptionInstalledWaiter( + SubscriptionService* subscription_service) + : subscription_service_(subscription_service) { + subscription_service_->AddObserver(this); + } + + ~SubscriptionInstalledWaiter() override { + subscription_service_->RemoveObserver(this); + } + + void WaitUntilSubscriptionsInstalled(std::vector subscriptions) { + awaited_subscriptions_ = std::move(subscriptions); + run_loop_.Run(); + } + + void OnSubscriptionInstalled(const GURL& subscription_url) override { + awaited_subscriptions_.erase( + base::ranges::remove(awaited_subscriptions_, subscription_url), + awaited_subscriptions_.end()); + if (awaited_subscriptions_.empty()) + run_loop_.Quit(); + } + + protected: + SubscriptionService* subscription_service_; + base::RunLoop run_loop_; + std::vector awaited_subscriptions_; +}; + +class AdblockFilteringConfigurationBrowserTest : public InProcessBrowserTest { + public: + void SetUpInProcessBrowserTestFixture() override { + InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); + host_resolver()->AddRule("*", "127.0.0.1"); + embedded_test_server()->ServeFilesFromSourceDirectory( + "chrome/test/data/adblock"); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + void SetUpOnMainThread() override { + auto* controller = + AdblockControllerFactory::GetForBrowserContext(browser()->profile()); + controller->RemoveCustomFilter(kAllowlistEverythingFilter); + } + + GURL BlockingFilterListUrl() { + return embedded_test_server()->GetURL( + "/filterlist_that_blocks_resource.txt"); + } + + GURL ElementHidingFilterListUrl() { + return embedded_test_server()->GetURL( + "/filterlist_that_hides_resource.txt"); + } + + GURL AllowingFilterListUrl() { + return embedded_test_server()->GetURL( + "/filterlist_that_allows_resource.txt"); + } + + GURL GetPageUrl() { + return embedded_test_server()->GetURL("test.org", "/innermost_frame.html"); + } + + void NavigateToPage() { + ASSERT_TRUE(NavigateToURL( + browser()->tab_strip_model()->GetActiveWebContents(), GetPageUrl())); + } + + std::unique_ptr MakeConfiguration( + std::string name) { + return std::make_unique( + browser()->profile()->GetPrefs(), name); + } + + void InstallFilteringConfiguration( + std::unique_ptr configuration) { + SubscriptionServiceFactory::GetForBrowserContext(browser()->profile()) + ->InstallFilteringConfiguration(std::move(configuration)); + } + + void WaitUntilSubscriptionsInstalled(std::vector subscriptions) { + SubscriptionInstalledWaiter waiter( + SubscriptionServiceFactory::GetForBrowserContext(browser()->profile())); + waiter.WaitUntilSubscriptionsInstalled(std::move(subscriptions)); + } + + std::string GetResourcesComputedStyle() { + const std::string javascript = + "window.getComputedStyle(document.getElementById('subresource'))." + "display"; + return content::EvalJs(browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(), + javascript) + .ExtractString(); + } + + void ExpectResourceBlocked() { + EXPECT_EQ("none", GetResourcesComputedStyle()); + } + + void ExpectResourceShown() { + EXPECT_EQ("inline", GetResourcesComputedStyle()); + } +}; + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + NoBlockingByDefault) { + auto configuration = MakeConfiguration("config"); + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ResourceBlockedByFilteringConfigurationsList) { + auto configuration = MakeConfiguration("config"); + configuration->AddFilterList(BlockingFilterListUrl()); + + InstallFilteringConfiguration(std::move(configuration)); + + WaitUntilSubscriptionsInstalled({BlockingFilterListUrl()}); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ResourceHiddenByFilteringConfigurationsList) { + auto configuration = MakeConfiguration("config"); + configuration->AddFilterList(ElementHidingFilterListUrl()); + + InstallFilteringConfiguration(std::move(configuration)); + + WaitUntilSubscriptionsInstalled({ElementHidingFilterListUrl()}); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ResourceAllowedByFilteringConfigurationsList) { + auto configuration = MakeConfiguration("config"); + configuration->AddFilterList(BlockingFilterListUrl()); + configuration->AddFilterList(ElementHidingFilterListUrl()); + configuration->AddFilterList(AllowingFilterListUrl()); + + InstallFilteringConfiguration(std::move(configuration)); + + WaitUntilSubscriptionsInstalled({BlockingFilterListUrl(), + AllowingFilterListUrl(), + ElementHidingFilterListUrl()}); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + BlockingTakesPrecedenceBetweenConfigurations) { + auto blocking_configuration = MakeConfiguration("blocking"); + blocking_configuration->AddFilterList(BlockingFilterListUrl()); + + auto allowing_configuration = MakeConfiguration("allowing"); + allowing_configuration->AddFilterList(AllowingFilterListUrl()); + + InstallFilteringConfiguration(std::move(blocking_configuration)); + InstallFilteringConfiguration(std::move(allowing_configuration)); + + WaitUntilSubscriptionsInstalled( + {BlockingFilterListUrl(), AllowingFilterListUrl()}); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ElementBlockedByCustomFilter) { + auto configuration = MakeConfiguration("config"); + configuration->AddCustomFilter("*resource.png"); + + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ElementAllowedByCustomFilter) { + auto configuration = MakeConfiguration("config"); + configuration->AddCustomFilter("*resource.png"); + configuration->AddCustomFilter("@@*resource.png"); + + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ElementAllowedByAllowedDomain) { + auto configuration = MakeConfiguration("config"); + configuration->AddCustomFilter("*resource.png"); + configuration->AddAllowedDomain(GetPageUrl().host()); + + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + PRE_CustomFiltersPersist) { + auto configuration = MakeConfiguration("persistent"); + // This custom filter will survive browser restart. + configuration->AddCustomFilter("*resource.png"); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + CustomFiltersPersist) { + auto configuration = MakeConfiguration("persistent"); + EXPECT_THAT(configuration->GetCustomFilters(), + testing::UnorderedElementsAre("*resource.png")); + + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + DisabledConfigurationDoesNotBlock) { + auto configuration = MakeConfiguration("config"); + configuration->AddCustomFilter("*resource.png"); + configuration->SetEnabled(false); + + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ConfigurationCanBeUsedAfterInstalling) { + auto configuration = MakeConfiguration("config"); + auto* configuration_ptr = configuration.get(); + + InstallFilteringConfiguration(std::move(configuration)); + + configuration_ptr->AddCustomFilter("*resource.png"); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + ConfigurationCanBeDisabledAfterInstalling) { + auto configuration = MakeConfiguration("config"); + auto* configuration_ptr = configuration.get(); + + InstallFilteringConfiguration(std::move(configuration)); + + configuration_ptr->AddCustomFilter("*resource.png"); + configuration_ptr->SetEnabled(false); + + NavigateToPage(); + ExpectResourceShown(); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + SubscriptionsDownloadedAfterConfigurationEnabled) { + auto configuration = MakeConfiguration("config"); + configuration->SetEnabled(false); + configuration->AddFilterList(BlockingFilterListUrl()); + configuration->AddFilterList(ElementHidingFilterListUrl()); + configuration->AddFilterList(AllowingFilterListUrl()); + auto* configuration_ptr = configuration.get(); + + InstallFilteringConfiguration(std::move(configuration)); + + configuration_ptr->SetEnabled(true); + + WaitUntilSubscriptionsInstalled({BlockingFilterListUrl(), + AllowingFilterListUrl(), + ElementHidingFilterListUrl()}); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + PRE_DownloadedSubscriptionsPersistOnDisk) { + auto configuration = MakeConfiguration("config"); + // This filter list setting will survive browser restart. + configuration->AddFilterList(BlockingFilterListUrl()); + + InstallFilteringConfiguration(std::move(configuration)); + + // This downloaded subscription won't need to be re-downloaded after restart. + WaitUntilSubscriptionsInstalled({BlockingFilterListUrl()}); +} + +IN_PROC_BROWSER_TEST_F(AdblockFilteringConfigurationBrowserTest, + DownloadedSubscriptionsPersistOnDisk) { + auto configuration = MakeConfiguration("config"); + InstallFilteringConfiguration(std::move(configuration)); + + NavigateToPage(); + ExpectResourceBlocked(); +} + +} // 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 = 3; + 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,197 @@ +/* + * 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/filtering_configuration_maintainer_impl.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( + scoped_refptr url_loader_factory) { + return std::make_unique(&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()); +} + +std::unique_ptr +MakeFilterConfigurationMaintainer( + content::BrowserContext* context, + FilteringConfiguration* configuration, + FilteringConfigurationMaintainerImpl::SubscriptionUpdatedCallback + observer) { + 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(); + + const std::string storage_dir = configuration->GetName() + "_subscriptions"; + + auto storage = std::make_unique( + context->GetPath().AppendASCII(storage_dir), + std::make_unique(prefs, + CurrentSchemaVersion()), + persistent_metadata); + auto downloader = std::make_unique( + utils::GetAppInfo(), + base::BindRepeating(&MakeOngoingSubscriptionRequest, url_loader_factory), + base::BindRepeating(&ConvertFileToFlatbuffer), persistent_metadata); + + auto maintainer = std::make_unique( + configuration, std::move(storage), std::move(downloader), + std::make_unique(), + MakeSubscriptionUpdater(), base::BindRepeating(&CustomFilterConverter), + persistent_metadata, observer); + maintainer->InitializeStorage(); + return maintainer; +} + +} // 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 { + return new SubscriptionServiceImpl( + base::BindRepeating(&MakeFilterConfigurationMaintainer, context)); +} + +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" @@ -102,6 +106,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/api_browser_context_keyed_service_factories.cc", "api/api_browser_context_keyed_service_factories.h", "api/autofill_private/autofill_private_api.cc", @@ -794,6 +800,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/cbor:cbor", "//components/commerce/core:pref_names", "//components/device_reauth", 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") @@ -65,6 +69,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/api_browser_context_keyed_service_factories.cc b/chrome/browser/extensions/api/api_browser_context_keyed_service_factories.cc --- a/chrome/browser/extensions/api/api_browser_context_keyed_service_factories.cc +++ b/chrome/browser/extensions/api/api_browser_context_keyed_service_factories.cc @@ -1,12 +1,17 @@ // Copyright 2022 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" #include "build/build_config.h" #include "build/chromeos_buildflags.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" @@ -58,6 +63,7 @@ namespace chrome_extensions { void EnsureApiBrowserContextKeyedServiceFactoriesBuilt() { extensions::ActivityLogAPI::GetFactoryInstance(); + extensions::AdblockPrivateAPI::GetFactoryInstance(); extensions::AutofillPrivateEventRouterFactory::GetInstance(); extensions::BluetoothLowEnergyAPI::GetFactoryInstance(); extensions::BookmarksAPI::GetFactoryInstance(); 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/bookmarks/common/bookmark_pref_names.h" #include "components/browsing_data/core/pref_names.h" @@ -167,6 +172,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" 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/commerce/core/pref_names.cc", "//components/dom_distiller/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/ash/app_list/app_list_syncable_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" @@ -138,6 +149,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" @@ -381,9 +393,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" @@ -192,7 +196,13 @@ IN_PROC_BROWSER_TEST_F(ProfileKeyedServiceBrowserTest, // clang-format off // List of services expected to be created for the Parent System Profile. std::set system_active_services { - "SiteDataCacheFacadeFactory" + "SiteDataCacheFacadeFactory", + + // eyeo Chromium SDK services: + "AdblockController", + "AdblockSubscriptionPersistentMetadata", + "AdblockSubscriptionService", + "AdblockTelemetryService", }; // clang-format on @@ -257,7 +267,7 @@ IN_PROC_BROWSER_TEST_F(ProfileKeyedServiceBrowserTest, "UkmBackgroundRecorderService", "UsbDeviceManager", "UsbDeviceResourceManager", - "sct_reporting::Factory" + "sct_reporting::Factory", }; // clang-format on @@ -492,6 +502,16 @@ IN_PROC_BROWSER_TEST_F(ProfileKeyedServiceBrowserTest, "feedback::FeedbackUploaderChrome", "sct_reporting::Factory", "ZeroSuggestCacheServiceFactory", + + // 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") @@ -92,6 +96,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,320 @@ +/* + * 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 || this.customFilterInput == "") return; + this.appendPrefListItem("adblock.custom_filters", this.customFilterInput); + this.customFilterInput = ""; + this.syncCustomFilters(); + } + + 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 || this.allowedDomainInput == "") return; + const cleanedUrl = this.cleanUrl(this.allowedDomainInput); + if (cleanedUrl == "") return; + this.appendPrefListItem("adblock.allowed_domains", cleanedUrl); + this.allowedDomainInput = ""; + this.syncAllowedDomains(); + } + + 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 || this.customSubscriptionInput == "") return; + this.appendPrefListItem("adblock.custom_subscriptions", this.customSubscriptionInput); + this.customSubscriptionInput = ""; + this.syncCustomSubscriptions(); + } +} + + +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 @@ +