LeOSium_webview/LeOS/patches/eyeo-beta-118.0.5993.48-ext...

5893 lines
226 KiB
Diff
Raw Normal View History

2023-11-18 11:46:19 +01:00
From: chromium-sdk <project_26591639_bot@noreply.gitlab.com>
Date: Thu, 12 Oct 2023 14:46:09 +0200
Subject: eyeo Browser Ad filtering Solution: Extension API Module
Based on Chromium 118.0.5993.48
Pre-requisites: eyeo Browser Ad filtering Solution: Base Module
---
chrome/browser/extensions/BUILD.gn | 9 +
chrome/browser/extensions/api/BUILD.gn | 5 +
.../adblock_private/adblock_private_api.cc | 674 ++++++++++++
.../api/adblock_private/adblock_private_api.h | 328 ++++++
.../adblock_private_apitest.cc | 984 ++++++++++++++++++
...browser_context_keyed_service_factories.cc | 8 +
.../eyeo_filtering_private_api.cc | 772 ++++++++++++++
.../eyeo_filtering_private_api.h | 360 +++++++
.../eyeo_filtering_private_apitest.cc | 161 +++
.../api/settings_private/prefs_util.cc | 19 +
...browser_context_keyed_service_factories.cc | 4 +
.../extension_function_registration_test.cc | 10 +
.../common/extensions/api/_api_features.json | 22 +
.../extensions/api/_permission_features.json | 12 +
.../common/extensions/api/adblock_private.idl | 174 ++++
chrome/common/extensions/api/api_sources.gni | 6 +
.../extensions/api/eyeo_filtering_private.idl | 201 ++++
.../permissions/chrome_api_permissions.cc | 8 +
.../permissions/permission_set_unittest.cc | 8 +
chrome/test/BUILD.gn | 6 +
.../api_test/adblock_private/empty.js | 14 +
.../api_test/adblock_private/main.html | 29 +
.../api_test/adblock_private/manifest.json | 32 +
.../api_test/adblock_private/some-popup.html | 24 +
.../api_test/adblock_private/test.html | 25 +
.../api_test/adblock_private/test.js | 538 ++++++++++
.../api_test/eyeo_filtering_private/empty.js | 14 +
.../api_test/eyeo_filtering_private/main.html | 29 +
.../eyeo_filtering_private/manifest.json | 31 +
.../api_test/eyeo_filtering_private/test.js | 460 ++++++++
.../browser/extension_event_histogram_value.h | 7 +-
.../common/mojom/api_permission_id.mojom | 6 +
tools/metrics/histograms/enums.xml | 7 +-
.../definitions/adblock_private.d.ts | 172 +++
.../definitions/eyeo_filtering_private.d.ts | 249 +++++
35 files changed, 5406 insertions(+), 2 deletions(-)
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/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.cc
create mode 100644 chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.h
create mode 100644 chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_apitest.cc
create mode 100644 chrome/common/extensions/api/adblock_private.idl
create mode 100644 chrome/common/extensions/api/eyeo_filtering_private.idl
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/some-popup.html
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 chrome/test/data/extensions/api_test/eyeo_filtering_private/empty.js
create mode 100644 chrome/test/data/extensions/api_test/eyeo_filtering_private/main.html
create mode 100644 chrome/test/data/extensions/api_test/eyeo_filtering_private/manifest.json
create mode 100644 chrome/test/data/extensions/api_test/eyeo_filtering_private/test.js
create mode 100644 tools/typescript/definitions/adblock_private.d.ts
create mode 100644 tools/typescript/definitions/eyeo_filtering_private.d.ts
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")
@@ -48,6 +52,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",
@@ -149,6 +155,8 @@ static_library("extensions") {
"api/extension_action/extension_action_api.h",
"api/extension_action/extension_page_actions_api_constants.cc",
"api/extension_action/extension_page_actions_api_constants.h",
+ "api/eyeo_filtering_private/eyeo_filtering_private_api.cc",
+ "api/eyeo_filtering_private/eyeo_filtering_private_api.h",
"api/favicon/favicon_util.cc",
"api/favicon/favicon_util.h",
"api/feedback_private/chrome_feedback_private_delegate.cc",
@@ -827,6 +835,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")
@@ -75,6 +79,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,674 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#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/resource_classification_runner_factory.h"
+#include "chrome/browser/adblock/session_stats_factory.h"
+#include "chrome/browser/adblock/subscription_service_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/common/adblock_utils.h"
+#include "components/adblock/core/common/content_type.h"
+#include "components/adblock/core/session_stats.h"
+#include "components/adblock/core/subscription/subscription_config.h"
+#include "components/sessions/core/session_id.h"
+#include "content/public/browser/web_contents.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+namespace {
+
+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* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(browser_context)
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ switch (action) {
+ case SubscriptionAction::kInstall:
+ adblock_configuration->AddFilterList(url);
+ break;
+ case SubscriptionAction::kUninstall:
+ adblock_configuration->RemoveFilterList(url);
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ return {};
+}
+
+std::vector<api::adblock_private::SessionStatsEntry> CopySessionsStats(
+ const std::map<GURL, long>& source) {
+ std::vector<api::adblock_private::SessionStatsEntry> 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";
+ case State::Unknown:
+ return "Unknown";
+ }
+ NOTREACHED();
+ return "";
+}
+
+std::vector<api::adblock_private::Subscription> CopySubscriptions(
+ const std::vector<scoped_refptr<adblock::Subscription>>
+ current_subscriptions) {
+ std::vector<api::adblock_private::Subscription> 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::SubscriptionServiceFactory::GetInstance());
+ DependsOn(adblock::ResourceClassificationRunnerFactory::GetInstance());
+ DependsOn(adblock::SessionStatsFactory::GetInstance());
+}
+
+// static
+BrowserContextKeyedAPIFactory<AdblockPrivateAPI>*
+AdblockPrivateAPI::GetFactoryInstance() {
+ static base::NoDestructor<BrowserContextKeyedAPIFactory<AdblockPrivateAPI>>
+ instance;
+ return instance.get();
+}
+
+class AdblockPrivateAPI::AdblockAPIEventRouter
+ : public adblock::ResourceClassificationRunner::Observer,
+ public adblock::SubscriptionService::SubscriptionObserver,
+ public adblock::FilteringConfiguration::Observer {
+ public:
+ explicit AdblockAPIEventRouter(content::BrowserContext* context)
+ : context_(context) {
+ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context_)
+ ->AddObserver(this);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context_);
+ subscription_service->AddObserver(this);
+ subscription_service->GetAdblockFilteringConfiguration()->AddObserver(this);
+ }
+
+ ~AdblockAPIEventRouter() override {
+ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context_)
+ ->RemoveObserver(this);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context_);
+ subscription_service->RemoveObserver(this);
+ subscription_service->GetAdblockFilteringConfiguration()->RemoveObserver(
+ this);
+ }
+
+ // adblock::ResourceClassificationRunner::Observer:
+ void OnAdMatched(const GURL& url,
+ adblock::FilterMatchResult match_result,
+ const std::vector<GURL>& parent_frame_urls,
+ adblock::ContentType content_type,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& subscription,
+ const std::string& configuration_name) override {
+ std::unique_ptr<Event> event;
+ api::adblock_private::AdInfo info = CreateAdInfoObject(
+ url, subscription, configuration_name, 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<Event>(
+ events::EYEO_EVENT, api::adblock_private::OnAdBlocked::kEventName,
+ api::adblock_private::OnAdBlocked::Create(info));
+ } else {
+ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule);
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT, api::adblock_private::OnAdAllowed::kEventName,
+ api::adblock_private::OnAdAllowed::Create(info));
+ }
+
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnPageAllowed(const GURL& url,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& subscription,
+ const std::string& configuration_name) override {
+ api::adblock_private::AdInfo info = CreateAdInfoObject(
+ url, subscription, configuration_name, render_frame_host);
+ info.parent_frame_urls = std::vector<std::string>{};
+ info.content_type = "";
+
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT, api::adblock_private::OnPageAllowed::kEventName,
+ api::adblock_private::OnPageAllowed::Create(info));
+
+ 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,
+ const std::string& configuration_name) override {
+ std::unique_ptr<Event> event;
+ api::adblock_private::AdInfo info = CreateAdInfoObject(
+ url, subscription, configuration_name, render_frame_host);
+ info.parent_frame_urls = std::vector<std::string>{opener_url.spec()};
+ info.content_type = "";
+
+ if (match_result == adblock::FilterMatchResult::kBlockRule) {
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT, api::adblock_private::OnPopupBlocked::kEventName,
+ api::adblock_private::OnPopupBlocked::Create(info));
+ } else {
+ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule);
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT, api::adblock_private::OnPopupAllowed::kEventName,
+ api::adblock_private::OnPopupAllowed::Create(info));
+ }
+
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ // adblock::SubscriptionService::SubscriptionObserver:
+ void OnSubscriptionInstalled(const GURL& url) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::adblock_private::OnSubscriptionUpdated::kEventName,
+ api::adblock_private::OnSubscriptionUpdated::Create(url.spec()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ // adblock::FilteringConfiguration::Observer:
+ void OnEnabledStateChanged(adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::adblock_private::OnEnabledStateChanged::kEventName,
+ api::adblock_private::OnEnabledStateChanged::Create());
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnFilterListsChanged(adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::adblock_private::OnFilterListsChanged::kEventName,
+ api::adblock_private::OnFilterListsChanged::Create());
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnAllowedDomainsChanged(
+ adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::adblock_private::OnAllowedDomainsChanged::kEventName,
+ api::adblock_private::OnAllowedDomainsChanged::Create());
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnCustomFiltersChanged(
+ adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::adblock_private::OnCustomFiltersChanged::kEventName,
+ api::adblock_private::OnCustomFiltersChanged::Create());
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ private:
+ api::adblock_private::AdInfo CreateAdInfoObject(
+ const GURL& url,
+ const GURL& subscription,
+ const std::string& configuration_name,
+ content::RenderFrameHost* render_frame_host) {
+ DCHECK(render_frame_host);
+ api::adblock_private::AdInfo info;
+ info.url = url.spec();
+ info.subscription = subscription.spec();
+ info.configuration_name = configuration_name;
+ 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;
+ }
+
+ raw_ptr<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);
+ EventRouter::Get(context_)->RegisterObserver(
+ this, api::adblock_private::OnEnabledStateChanged::kEventName);
+ EventRouter::Get(context_)->RegisterObserver(
+ this, api::adblock_private::OnFilterListsChanged::kEventName);
+ EventRouter::Get(context_)->RegisterObserver(
+ this, api::adblock_private::OnAllowedDomainsChanged::kEventName);
+ EventRouter::Get(context_)->RegisterObserver(
+ this, api::adblock_private::OnCustomFiltersChanged::kEventName);
+ }
+ // Make sure SessionStats is created so it will start collectings stats
+ adblock::SessionStatsFactory::GetForBrowserContext(context);
+}
+
+AdblockPrivateAPI::~AdblockPrivateAPI() = default;
+
+void AdblockPrivateAPI::OnListenerAdded(
+ const extensions::EventListenerInfo& details) {
+ event_router_ =
+ std::make_unique<AdblockPrivateAPI::AdblockAPIEventRouter>(context_);
+ EventRouter::Get(context_)->UnregisterObserver(this);
+}
+
+namespace api {
+
+AdblockPrivateSetEnabledFunction::AdblockPrivateSetEnabledFunction() {}
+
+AdblockPrivateSetEnabledFunction::~AdblockPrivateSetEnabledFunction() {}
+
+ExtensionFunction::ResponseAction AdblockPrivateSetEnabledFunction::Run() {
+ absl::optional<api::adblock_private::SetEnabled::Params> params =
+ api::adblock_private::SetEnabled::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ adblock_configuration->SetEnabled(params->enabled);
+ return RespondNow(NoArguments());
+}
+
+AdblockPrivateIsEnabledFunction::AdblockPrivateIsEnabledFunction() {}
+
+AdblockPrivateIsEnabledFunction::~AdblockPrivateIsEnabledFunction() {}
+
+ExtensionFunction::ResponseAction AdblockPrivateIsEnabledFunction::Run() {
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ return RespondNow(
+ ArgumentList(api::adblock_private::IsEnabled::Results::Create(
+ adblock_configuration->IsEnabled())));
+}
+
+AdblockPrivateSetAcceptableAdsEnabledFunction::
+ AdblockPrivateSetAcceptableAdsEnabledFunction() {}
+
+AdblockPrivateSetAcceptableAdsEnabledFunction::
+ ~AdblockPrivateSetAcceptableAdsEnabledFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateSetAcceptableAdsEnabledFunction::Run() {
+ absl::optional<api::adblock_private::SetAcceptableAdsEnabled::Params> params =
+ api::adblock_private::SetAcceptableAdsEnabled::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ if (params->enabled) {
+ adblock_configuration->AddFilterList(adblock::AcceptableAdsUrl());
+ } else {
+ adblock_configuration->RemoveFilterList(adblock::AcceptableAdsUrl());
+ }
+
+ return RespondNow(NoArguments());
+}
+
+AdblockPrivateIsAcceptableAdsEnabledFunction::
+ AdblockPrivateIsAcceptableAdsEnabledFunction() {}
+
+AdblockPrivateIsAcceptableAdsEnabledFunction::
+ ~AdblockPrivateIsAcceptableAdsEnabledFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateIsAcceptableAdsEnabledFunction::Run() {
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ return RespondNow(ArgumentList(
+ api::adblock_private::IsAcceptableAdsEnabled::Results::Create(
+ base::ranges::any_of(adblock_configuration->GetFilterLists(),
+ [&](const auto& url) {
+ return url == adblock::AcceptableAdsUrl();
+ }))));
+}
+
+AdblockPrivateGetBuiltInSubscriptionsFunction::
+ AdblockPrivateGetBuiltInSubscriptionsFunction() {}
+
+AdblockPrivateGetBuiltInSubscriptionsFunction::
+ ~AdblockPrivateGetBuiltInSubscriptionsFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateGetBuiltInSubscriptionsFunction::Run() {
+ auto recommended = adblock::config::GetKnownSubscriptions();
+ std::vector<api::adblock_private::BuiltInSubscription> 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)));
+}
+
+AdblockPrivateInstallSubscriptionFunction::
+ AdblockPrivateInstallSubscriptionFunction() {}
+
+AdblockPrivateInstallSubscriptionFunction::
+ ~AdblockPrivateInstallSubscriptionFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateInstallSubscriptionFunction::Run() {
+ absl::optional<api::adblock_private::InstallSubscription::Params> 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() {
+ absl::optional<api::adblock_private::UninstallSubscription::Params> 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* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context());
+ auto* adblock_configuration =
+ subscription_service->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ return RespondNow(ArgumentList(
+ api::adblock_private::GetInstalledSubscriptions::Results::Create(
+ CopySubscriptions(subscription_service->GetCurrentSubscriptions(
+ subscription_service->GetAdblockFilteringConfiguration())))));
+}
+
+AdblockPrivateAddAllowedDomainFunction::
+ AdblockPrivateAddAllowedDomainFunction() {}
+
+AdblockPrivateAddAllowedDomainFunction::
+ ~AdblockPrivateAddAllowedDomainFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateAddAllowedDomainFunction::Run() {
+ absl::optional<api::adblock_private::AddAllowedDomain::Params> params =
+ api::adblock_private::AddAllowedDomain::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ adblock_configuration->AddAllowedDomain(params->domain);
+ return RespondNow(NoArguments());
+}
+
+AdblockPrivateRemoveAllowedDomainFunction::
+ AdblockPrivateRemoveAllowedDomainFunction() {}
+
+AdblockPrivateRemoveAllowedDomainFunction::
+ ~AdblockPrivateRemoveAllowedDomainFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateRemoveAllowedDomainFunction::Run() {
+ absl::optional<api::adblock_private::RemoveAllowedDomain::Params> params =
+ api::adblock_private::RemoveAllowedDomain::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ adblock_configuration->RemoveAllowedDomain(params->domain);
+
+ return RespondNow(NoArguments());
+}
+
+AdblockPrivateGetAllowedDomainsFunction::
+ AdblockPrivateGetAllowedDomainsFunction() {}
+
+AdblockPrivateGetAllowedDomainsFunction::
+ ~AdblockPrivateGetAllowedDomainsFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateGetAllowedDomainsFunction::Run() {
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ return RespondNow(
+ ArgumentList(api::adblock_private::GetAllowedDomains::Results::Create(
+ adblock_configuration->GetAllowedDomains())));
+}
+
+AdblockPrivateAddCustomFilterFunction::AdblockPrivateAddCustomFilterFunction() {
+}
+
+AdblockPrivateAddCustomFilterFunction::
+ ~AdblockPrivateAddCustomFilterFunction() {}
+
+ExtensionFunction::ResponseAction AdblockPrivateAddCustomFilterFunction::Run() {
+ absl::optional<api::adblock_private::AddCustomFilter::Params> params =
+ api::adblock_private::AddCustomFilter::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ adblock_configuration->AddCustomFilter(params->filter);
+ return RespondNow(NoArguments());
+}
+
+AdblockPrivateRemoveCustomFilterFunction::
+ AdblockPrivateRemoveCustomFilterFunction() {}
+
+AdblockPrivateRemoveCustomFilterFunction::
+ ~AdblockPrivateRemoveCustomFilterFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateGetCustomFiltersFunction::Run() {
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ return RespondNow(
+ ArgumentList(api::adblock_private::GetCustomFilters::Results::Create(
+ adblock_configuration->GetCustomFilters())));
+}
+
+AdblockPrivateGetCustomFiltersFunction::
+ AdblockPrivateGetCustomFiltersFunction() {}
+
+AdblockPrivateGetCustomFiltersFunction::
+ ~AdblockPrivateGetCustomFiltersFunction() {}
+
+ExtensionFunction::ResponseAction
+AdblockPrivateRemoveCustomFilterFunction::Run() {
+ absl::optional<api::adblock_private::RemoveCustomFilter::Params> params =
+ api::adblock_private::RemoveCustomFilter::Params::Create(args());
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context())
+ ->GetAdblockFilteringConfiguration();
+ DCHECK(adblock_configuration)
+ << "adblock_private expects \"adblock\" configuration";
+ adblock_configuration->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,328 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_ADBLOCK_PRIVATE_ADBLOCK_PRIVATE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_ADBLOCK_PRIVATE_ADBLOCK_PRIVATE_API_H_
+
+#include "base/memory/raw_ptr.h"
+#include "chrome/common/extensions/api/adblock_private.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<AdblockPrivateAPI>* GetFactoryInstance();
+
+ static AdblockPrivateAPI* Get(content::BrowserContext* context);
+
+ explicit AdblockPrivateAPI(content::BrowserContext* context);
+ ~AdblockPrivateAPI() override;
+ friend class BrowserContextKeyedAPIFactory<AdblockPrivateAPI>;
+
+ // 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:
+ raw_ptr<content::BrowserContext> context_;
+ class AdblockAPIEventRouter;
+ std::unique_ptr<AdblockAPIEventRouter> event_router_;
+};
+
+template <>
+void BrowserContextKeyedAPIFactory<
+ AdblockPrivateAPI>::DeclareFactoryDependencies();
+
+namespace api {
+
+class AdblockPrivateSetEnabledFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("adblockPrivate.setEnabled", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ AdblockPrivateGetBuiltInSubscriptionsFunction();
+
+ private:
+ ~AdblockPrivateGetBuiltInSubscriptionsFunction() override;
+
+ // ExtensionFunction:
+ ResponseAction Run() override;
+
+ AdblockPrivateGetBuiltInSubscriptionsFunction(
+ const AdblockPrivateGetBuiltInSubscriptionsFunction&) = delete;
+ AdblockPrivateGetBuiltInSubscriptionsFunction& operator=(
+ const AdblockPrivateGetBuiltInSubscriptionsFunction&) = delete;
+};
+
+class AdblockPrivateInstallSubscriptionFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("adblockPrivate.installSubscription", UNKNOWN)
+ 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", UNKNOWN)
+ 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",
+ UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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", UNKNOWN)
+ 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",
+ UNKNOWN)
+ 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",
+ UNKNOWN)
+ 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,984 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "chrome/browser/adblock/adblock_content_browser_client.h"
+#include "chrome/browser/adblock/subscription_service_factory.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/ssl/https_upgrades_interceptor.h"
+#include "chrome/browser/ssl/https_upgrades_util.h"
+#include "chrome/common/chrome_switches.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/common/adblock_constants.h"
+#include "components/adblock/core/subscription/subscription_config.h"
+#include "components/adblock/core/subscription/subscription_service.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"
+
+namespace extensions {
+
+namespace {
+enum class Mode { Normal, Incognito };
+enum class EyeoExtensionApi { Old, New };
+} // namespace
+
+class AdblockPrivateApiTest : public ExtensionApiTest,
+ public testing::WithParamInterface<Mode> {
+ public:
+ AdblockPrivateApiTest() {}
+ ~AdblockPrivateApiTest() override = default;
+ AdblockPrivateApiTest(const AdblockPrivateApiTest&) = delete;
+ AdblockPrivateApiTest& operator=(const AdblockPrivateApiTest&) = delete;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
+ if (IsIncognito()) {
+ command_line->AppendSwitch(switches::kIncognito);
+ }
+ }
+
+ 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::SubscriptionServiceFactory::GetForBrowserContext(
+ browser()->profile())
+ ->GetAdblockFilteringConfiguration()
+ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter);
+
+ AdblockContentBrowserClient::ForceAdblockProxyForTesting();
+ }
+
+ bool IsIncognito() { return GetParam() == Mode::Incognito; }
+
+ bool RunTest(const std::string& subtest) {
+ const std::string page_url = "main.html?subtest=" + subtest;
+ return RunExtensionTest("adblock_private",
+ {.extension_url = page_url.c_str()},
+ {.allow_in_incognito = IsIncognito(),
+ .load_as_component = !IsIncognito()});
+ }
+
+ bool RunTestWithParams(const std::string& subtest,
+ const std::map<std::string, std::string>& 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,
+ std::map<std::string, std::string> params = {{}}) {
+ 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;
+ }
+ params.insert(
+ {"subscription_url", https_server.GetURL(subscription_path).spec()});
+ return RunTestWithParams(subtest, params);
+ }
+
+ std::unique_ptr<net::test_server::HttpResponse>
+ 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<net::test_server::BasicHttpResponse>();
+ 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;
+ }
+
+ std::map<std::string, std::string> SubscriptionsManagementSetup() {
+ DCHECK(browser()->profile());
+ auto selected = adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser()->profile())
+ ->GetAdblockFilteringConfiguration()
+ ->GetFilterLists();
+ const auto easylist = std::find_if(
+ selected.begin(), selected.end(), [&](const GURL& subscription) {
+ return base::EndsWith(subscription.path_piece(), "easylist.txt");
+ });
+ const auto exceptions = std::find_if(
+ selected.begin(), selected.end(), [&](const GURL& subscription) {
+ return base::EndsWith(subscription.path_piece(),
+ "exceptionrules.txt");
+ });
+ const auto snippets = std::find_if(
+ selected.begin(), selected.end(), [&](const GURL& subscription) {
+ return base::EndsWith(subscription.path_piece(),
+ "abp-filters-anti-cv.txt");
+ });
+ if (easylist == selected.end() || exceptions == selected.end() ||
+ snippets == selected.end()) {
+ return std::map<std::string, std::string>{};
+ }
+ return std::map<std::string, std::string>{
+ {"easylist", easylist->spec()},
+ {"exceptions", exceptions->spec()},
+ {"snippets", snippets->spec()}};
+ }
+};
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SetAndCheckEnabled) {
+ EXPECT_TRUE(RunTest("setEnabled_isEnabled")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SetAndCheckEnabledNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("setEnabled_isEnabled",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SetAndCheckAAEnabled) {
+ EXPECT_TRUE(RunTest("setAAEnabled_isAAEnabled")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SetAndCheckAAEnabledNewAPI) {
+ EXPECT_TRUE(RunTest("setAAEnabled_isAAEnabled_newAPI")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, GetBuiltInSubscriptions) {
+ EXPECT_TRUE(RunTest("getBuiltInSubscriptions")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ InstalledSubscriptionsDataSchema) {
+ EXPECT_TRUE(RunTest("installedSubscriptionsDataSchema")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ InstalledSubscriptionsDataSchemaNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("installedSubscriptionsDataSchema",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ InstalledSubscriptionsDataSchemaConfigDisabled) {
+ EXPECT_TRUE(RunTestWithParams("installedSubscriptionsDataSchema",
+ {{"disabled", "true"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ InstalledSubscriptionsDataSchemaConfigDisabledNewAPI) {
+ EXPECT_TRUE(RunTestWithParams(
+ "installedSubscriptionsDataSchema",
+ {{"api", "eyeoFilteringPrivate"}, {"disabled", "true"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, InstallSubscriptionInvalidURL) {
+ EXPECT_TRUE(RunTest("installSubscriptionInvalidURL")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ InstallSubscriptionInvalidURLNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("installSubscriptionInvalidURL",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, UninstallSubscriptionInvalidURL) {
+ EXPECT_TRUE(RunTest("uninstallSubscriptionInvalidURL")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ UninstallSubscriptionInvalidURLNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("uninstallSubscriptionInvalidURL",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SubscriptionsManagement) {
+ auto params = SubscriptionsManagementSetup();
+ if (params.empty()) {
+ // Since default configuration has been changed let's skip this test
+ return;
+ }
+ EXPECT_TRUE(RunTestWithParams("subscriptionsManagement", params)) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SubscriptionsManagementNewAPI) {
+ auto params = SubscriptionsManagementSetup();
+ if (params.empty()) {
+ // Since default configuration has been changed let's skip this test
+ return;
+ }
+ params.insert({"api", "eyeoFilteringPrivate"});
+ SubscriptionsManagementSetup();
+ EXPECT_TRUE(RunTestWithParams("subscriptionsManagement", params)) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ SubscriptionsManagementConfigDisabled) {
+ auto params = SubscriptionsManagementSetup();
+ if (params.empty()) {
+ // Since default configuration has been changed let's skip this test
+ return;
+ }
+ params.insert({"disabled", "true"});
+ EXPECT_TRUE(RunTestWithParams("subscriptionsManagement", params)) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest,
+ SubscriptionsManagementConfigDisabledNewAPI) {
+ auto params = SubscriptionsManagementSetup();
+ if (params.empty()) {
+ // Since default configuration has been changed let's skip this test
+ return;
+ }
+ params.insert({"api", "eyeoFilteringPrivate"});
+ params.insert({"disabled", "true"});
+ SubscriptionsManagementSetup();
+ EXPECT_TRUE(RunTestWithParams("subscriptionsManagement", params)) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, AllowedDomainsManagement) {
+ EXPECT_TRUE(RunTest("allowedDomainsManagement")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, AllowedDomainsManagementNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("allowedDomainsManagement",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, CustomFiltersManagement) {
+ EXPECT_TRUE(RunTest("customFiltersManagement")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, CustomFiltersManagementNewAPI) {
+ EXPECT_TRUE(RunTestWithParams("customFiltersManagement",
+ {{"api", "eyeoFilteringPrivate"}}))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(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_P(AdblockPrivateApiTest, AdBlockedEventsNewAPI) {
+ std::string subscription_path = "/testeventssub.txt";
+ std::string subscription_filters = "test1.png";
+ std::map<std::string, std::string> params = {{"api", "eyeoFilteringPrivate"}};
+ EXPECT_TRUE(RunTestWithServer("adBlockedEvents", subscription_path,
+ subscription_filters, std::move(params)))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(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_P(AdblockPrivateApiTest, AdAllowedEventsNewAPI) {
+ std::string subscription_path = "/testeventssub.txt";
+ std::string subscription_filters = "test2.png\n@@test2.png";
+ std::map<std::string, std::string> params = {{"api", "eyeoFilteringPrivate"}};
+ EXPECT_TRUE(RunTestWithServer("adAllowedEvents", subscription_path,
+ subscription_filters, std::move(params)))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(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_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, SessionStatsNewAPI) {
+ std::string subscription_path = "/teststatssub.txt";
+ std::string subscription_filters = "test3.png\ntest4.png\n@@test4.png";
+ std::map<std::string, std::string> params = {{"api", "eyeoFilteringPrivate"}};
+ EXPECT_TRUE(RunTestWithServer("sessionStats", subscription_path,
+ subscription_filters, std::move(params)))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, AllowedDomainsEvent) {
+ EXPECT_TRUE(RunTest("allowedDomainsEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, EnabledStateEvent) {
+ EXPECT_TRUE(RunTest("enabledStateEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, FilterListsEvent) {
+ EXPECT_TRUE(RunTest("filterListsEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiTest, CustomFiltersEvent) {
+ EXPECT_TRUE(RunTest("customFiltersEvent")) << message_;
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+ AdblockPrivateApiTest,
+ testing::Values(Mode::Normal, Mode::Incognito));
+
+class AdblockPrivateApiBackgroundPageTest
+ : public ExtensionApiTest,
+ public testing::WithParamInterface<std::tuple<EyeoExtensionApi, Mode>> {
+ public:
+ AdblockPrivateApiBackgroundPageTest() {}
+ ~AdblockPrivateApiBackgroundPageTest() override = default;
+ AdblockPrivateApiBackgroundPageTest(
+ const AdblockPrivateApiBackgroundPageTest&) = delete;
+ AdblockPrivateApiBackgroundPageTest& operator=(
+ const AdblockPrivateApiBackgroundPageTest&) = delete;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
+ if (IsIncognito()) {
+ command_line->AppendSwitch(switches::kIncognito);
+ }
+ }
+
+ protected:
+ void SetUpOnMainThread() override {
+ ExtensionApiTest::SetUpOnMainThread();
+
+ https_test_server_ = std::make_unique<net::EmbeddedTestServer>(
+ net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
+ https_test_server_->ServeFilesFromSourceDirectory(
+ "chrome/test/data/extensions/api_test/adblock_private");
+ embedded_test_server()->ServeFilesFromSourceDirectory(
+ "chrome/test/data/extensions/api_test/adblock_private");
+ HttpsUpgradesInterceptor::SetHttpsPortForTesting(
+ https_test_server_->port());
+ HttpsUpgradesInterceptor::SetHttpPortForTesting(
+ embedded_test_server()->port());
+ ASSERT_TRUE(https_test_server_->Start());
+ AllowHttpForHostnamesForTesting({"example.com"},
+ browser()->profile()->GetPrefs());
+
+ // Map example.com to localhost.
+ host_resolver()->AddRule("example.com", "127.0.0.1");
+ ASSERT_TRUE(StartEmbeddedTestServer());
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser()->profile())
+ ->GetAdblockFilteringConfiguration()
+ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter);
+ }
+
+ bool IsOldApi() { return std::get<0>(GetParam()) == EyeoExtensionApi::Old; }
+
+ bool IsIncognito() { return std::get<1>(GetParam()) == Mode::Incognito; }
+
+ void ExecuteScript(const std::string& js_code) const {
+ content::WebContents* web_contents =
+ browser()->tab_strip_model()->GetWebContentsAt(0);
+ ASSERT_TRUE(content::ExecJs(web_contents->GetPrimaryMainFrame(), js_code));
+ }
+
+ std::string ExecuteScriptInBackgroundPage(const std::string& extension_id,
+ const std::string& script) {
+ return ExtensionApiTest::ExecuteScriptInBackgroundPage(extension_id, script)
+ .GetString();
+ }
+
+ void SetupApiObjectAndMethods(const std::string& extension_id) {
+ std::string setup_script;
+ if (IsOldApi()) {
+ setup_script =
+ "var apiObject = chrome.adblockPrivate;"
+ "var sessionAllowedCount = 'getSessionAllowedAdsCount';"
+ "var sessionBlockedCount = 'getSessionBlockedAdsCount';"
+ "var onAllowedEvent = 'onAdAllowed';"
+ "var onBlockedEvent = 'onAdBlocked';"
+ "chrome.test.sendScriptResult('');";
+ } else {
+ setup_script =
+ "var apiObject = chrome.eyeoFilteringPrivate;"
+ "var sessionAllowedCount = 'getSessionAllowedRequestsCount';"
+ "var sessionBlockedCount = 'getSessionBlockedRequestsCount';"
+ "var onAllowedEvent = 'onRequestAllowed';"
+ "var onBlockedEvent = 'onRequestBlocked';"
+ "chrome.test.sendScriptResult('');";
+ }
+ ExecuteScriptInBackgroundPage(extension_id, setup_script);
+ }
+
+ std::unique_ptr<net::EmbeddedTestServer> https_test_server_;
+};
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiBackgroundPageTest, PageAllowedEvents) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ constexpr char kSetListenersScript[] = R"(
+ var testData = {};
+ testData.pageAllowedCount = 0;
+ apiObject.onPageAllowed.addListener(function(e) {
+ if (!e.url.endsWith('test.html')) {
+ return;
+ }
+ testData.pageAllowedCount = testData.pageAllowedCount + 1;
+ });
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kReadCountersScript[] = R"(
+ chrome.test.sendScriptResult(testData.pageAllowedCount.toString());
+ )";
+
+ constexpr char kAllowDomainScript[] = R"(
+ apiObject.addAllowedDomain(%s'example.com');
+ chrome.test.sendScriptResult('');
+ )";
+
+ const GURL test_url = https_test_server_->GetURL(
+ "example.com", "/extensions/api_test/adblock_private/test.html");
+
+ SetupApiObjectAndMethods(extension->id());
+
+ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript);
+
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ(
+ "0", ExecuteScriptInBackgroundPage(extension->id(), kReadCountersScript));
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kAllowDomainScript, IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ(
+ "1", ExecuteScriptInBackgroundPage(extension->id(), kReadCountersScript));
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiBackgroundPageTest, PageAllowedStats) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ constexpr char kReadAllowedStatsScript[] = R"(
+ apiObject[sessionAllowedCount](function(sessionStats) {
+ let count = 0;
+ for (const entry of sessionStats) {
+ if (entry.url === 'adblock:custom') {
+ count = entry.count;
+ }
+ }
+ chrome.test.sendScriptResult(count.toString());
+ });
+ )";
+
+ constexpr char kAllowDomainScript[] = R"(
+ apiObject.addAllowedDomain(%s'example.com');
+ chrome.test.sendScriptResult('');
+ )";
+
+ const GURL test_url = https_test_server_->GetURL(
+ "example.com", "/extensions/api_test/adblock_private/test.html");
+
+ SetupApiObjectAndMethods(extension->id());
+
+ int initial_value = std::stoi(
+ ExecuteScriptInBackgroundPage(extension->id(), kReadAllowedStatsScript));
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kAllowDomainScript, IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+
+ ASSERT_EQ(initial_value + 1, std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), kReadAllowedStatsScript)));
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiBackgroundPageTest, PopupEvents) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ constexpr char kSetListenersScript[] = R"(
+ var testData = {};
+ testData.popupBlockedCount = 0;
+ testData.popupAllowedCount = 0;
+ apiObject.onPopupAllowed.addListener(function(e, blocked) {
+ if (!e.url.endsWith('some-popup.html')) {
+ return;
+ }
+ testData.popupAllowedCount = testData.popupAllowedCount + 1;
+ });
+ apiObject.onPopupBlocked.addListener(function(e, blocked) {
+ if (!e.url.endsWith('some-popup.html')) {
+ return;
+ }
+ testData.popupBlockedCount = testData.popupBlockedCount + 1;
+ });
+ chrome.test.sendScriptResult('');
+ )";
+
+ auto read_allowed_stats_script = [](int expected) {
+ std::string script = base::StringPrintf(
+ R"(
+ var intervalAllowedId = setInterval(function() {
+ if (testData.popupAllowedCount == %d) {
+ if (intervalAllowedId) {
+ clearInterval(intervalAllowedId);
+ intervalAllowedId = null;
+ }
+ chrome.test.sendScriptResult(
+ testData.popupAllowedCount.toString());
+ }
+ }, 100))",
+ expected);
+ return script;
+ };
+
+ auto read_blocked_stats_script = [](int expected) {
+ std::string script = base::StringPrintf(
+ R"(
+ var intervalBlockedId = setInterval(function() {
+ if (testData.popupBlockedCount == %d) {
+ if (intervalBlockedId) {
+ clearInterval(intervalBlockedId);
+ intervalBlockedId = null;
+ }
+ chrome.test.sendScriptResult(
+ testData.popupBlockedCount.toString());
+ }
+ }, 100))",
+ expected);
+ return script;
+ };
+
+ constexpr char kBlockPopupScript[] = R"(
+ apiObject.addCustomFilter(%s'some-popup.html^$popup');
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kAllowPopupScript[] = R"(
+ apiObject.addCustomFilter(%s'@@some-popup.html^$popup');
+ chrome.test.sendScriptResult('');
+ )";
+
+ const GURL test_url =
+ embedded_test_server()->GetURL("example.com", "/test.html");
+ constexpr char kOpenPopupScript[] =
+ "document.getElementById('popup_id').click()";
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ SetupApiObjectAndMethods(extension->id());
+
+ ExecuteScriptInBackgroundPage(extension->id(), kSetListenersScript);
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kBlockPopupScript, IsOldApi() ? "" : "'adblock', "));
+ ExecuteScript(kOpenPopupScript);
+ ASSERT_EQ(1, std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), read_blocked_stats_script(1))));
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kAllowPopupScript, IsOldApi() ? "" : "'adblock', "));
+ ExecuteScript(kOpenPopupScript);
+ ASSERT_EQ(1, std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), read_allowed_stats_script(1))));
+ ASSERT_EQ(1, std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), read_blocked_stats_script(1))));
+}
+
+IN_PROC_BROWSER_TEST_P(AdblockPrivateApiBackgroundPageTest, PopupStats) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ auto read_allowed_stats_script = [](int expected) {
+ std::string script = base::StringPrintf(
+ R"(
+ var intervalAllowedId = setInterval(function() {
+ apiObject[sessionAllowedCount](function(sessionStats) {
+ let count = 0;
+ for (const entry of sessionStats) {
+ if (entry.url === 'adblock:custom') {
+ count = entry.count;
+ }
+ }
+ if (%d == 0 || count == %d) {
+ if (intervalAllowedId) {
+ clearInterval(intervalAllowedId);
+ intervalAllowedId = null;
+ }
+ chrome.test.sendScriptResult(count.toString());
+ }
+ }
+ )}, 100))",
+ expected, expected);
+ return script;
+ };
+
+ auto read_blocked_stats_script = [](int expected) {
+ std::string script = base::StringPrintf(
+ R"(
+ var intervalBlockedId = setInterval(function() {
+ apiObject[sessionBlockedCount](function(sessionStats) {
+ let count = 0;
+ for (const entry of sessionStats) {
+ if (entry.url === 'adblock:custom') {
+ count = entry.count;
+ }
+ }
+ if (%d == 0 || count == %d) {
+ if (intervalBlockedId) {
+ clearInterval(intervalBlockedId);
+ intervalBlockedId = null;
+ }
+ chrome.test.sendScriptResult(count.toString());
+ }
+ }
+ )}, 100))",
+ expected, expected);
+ return script;
+ };
+
+ constexpr char kBlockPopupScript[] = R"(
+ apiObject.addCustomFilter(%s'some-popup.html^$popup');
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kAllowPopupScript[] = R"(
+ apiObject.addCustomFilter(%s'@@some-popup.html^$popup');
+ chrome.test.sendScriptResult('');
+ )";
+
+ const GURL test_url =
+ embedded_test_server()->GetURL("example.com", "/test.html");
+ constexpr char kOpenPopupScript[] =
+ "document.getElementById('popup_id').click()";
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ SetupApiObjectAndMethods(extension->id());
+
+ int initial_allowed_value = std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), read_allowed_stats_script(0)));
+ int initial_blocked_value = std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(), read_blocked_stats_script(0)));
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kBlockPopupScript, IsOldApi() ? "" : "'adblock', "));
+ ExecuteScript(kOpenPopupScript);
+ ASSERT_EQ(initial_blocked_value + 1,
+ std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(),
+ read_blocked_stats_script(initial_blocked_value + 1))));
+
+ ExecuteScriptInBackgroundPage(
+ extension->id(),
+ base::StringPrintf(kAllowPopupScript, IsOldApi() ? "" : "'adblock', "));
+ ExecuteScript(kOpenPopupScript);
+ ASSERT_EQ(initial_allowed_value + 1,
+ std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(),
+ read_allowed_stats_script(initial_allowed_value + 1))));
+ ASSERT_EQ(initial_blocked_value + 1,
+ std::stoi(ExecuteScriptInBackgroundPage(
+ extension->id(),
+ read_blocked_stats_script(initial_blocked_value + 1))));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ AdblockPrivateApiBackgroundPageTest,
+ testing::Combine(testing::Values(EyeoExtensionApi::Old,
+ EyeoExtensionApi::New),
+ testing::Values(Mode::Normal, Mode::Incognito)));
+
+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::SubscriptionServiceFactory::GetForBrowserContext(
+ browser()->profile())
+ ->GetAdblockFilteringConfiguration()
+ ->RemoveCustomFilter(adblock::kAllowlistEverythingFilter);
+ }
+
+ std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
+ const net::test_server::HttpRequest& request) {
+ if (base::EndsWith(request.relative_url, before_redirect_domain,
+ base::CompareCase::SENSITIVE)) {
+ std::unique_ptr<net::test_server::BasicHttpResponse> 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<net::test_server::BasicHttpResponse>();
+ 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 = "<img src=\"" + url.spec() + "\">";
+ 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_P(AdblockPrivateApiBackgroundPageTestWithRedirect,
+ PageAllowedEvents) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ constexpr char kSetListenersScript[] = R"(
+ var testData = {};
+ testData.pageAllowedBeforeRedirectCount = 0;
+ testData.pageAllowedAfterRedirectCount = 0;
+ apiObject.onPageAllowed.addListener(function(e) {
+ if (e.url.includes('before-redirect.com')) {
+ ++testData.pageAllowedBeforeRedirectCount;
+ } else if (e.url.includes('after-redirect.com')) {
+ ++testData.pageAllowedAfterRedirectCount;
+ }
+ });
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kReadCountersScript[] = R"(
+ chrome.test.sendScriptResult(
+ testData.pageAllowedBeforeRedirectCount + '-' +
+ testData.pageAllowedAfterRedirectCount);
+ )";
+
+ constexpr char kAddAllowDomainScript[] = R"(
+ apiObject.addAllowedDomain(%s'after-redirect.com');
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kRemoveAllowDomainScript[] = R"(
+ apiObject.removeAllowedDomain(%s'after-redirect.com');
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kAddBlockDomainFilterScript[] = R"(
+ apiObject.addCustomFilter(%s'after-redirect.com');
+ chrome.test.sendScriptResult('');
+ )";
+
+ // 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);
+
+ SetupApiObjectAndMethods(extension->id());
+
+ 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(), base::StringPrintf(kAddAllowDomainScript,
+ IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ("0-1", ExecuteScriptInBackgroundPage(extension->id(),
+ kReadCountersScript));
+ // Just block filter
+ ExecuteScriptInBackgroundPage(
+ extension->id(), base::StringPrintf(kAddBlockDomainFilterScript,
+ IsOldApi() ? "" : "'adblock', "));
+ ExecuteScriptInBackgroundPage(
+ extension->id(), base::StringPrintf(kRemoveAllowDomainScript,
+ IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ("0-1", ExecuteScriptInBackgroundPage(extension->id(),
+ kReadCountersScript));
+
+ // Allow and block filter
+ ExecuteScriptInBackgroundPage(
+ extension->id(), base::StringPrintf(kAddAllowDomainScript,
+ IsOldApi() ? "" : "'adblock', "));
+ 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_P(AdblockPrivateApiBackgroundPageTestWithRedirect,
+ AdMatchedEvents) {
+ const Extension* extension =
+ LoadExtension(test_data_dir_.AppendASCII("adblock_private"),
+ {.allow_in_incognito = IsIncognito()});
+ ASSERT_TRUE(extension);
+
+ constexpr char kSetListenersScript[] = R"(
+ var testData = {};
+ testData.adBlockedCount = 0;
+ testData.adAllowedCount = 0;
+ apiObject[onBlockedEvent].addListener(function(e) {
+ if (e.url.includes('http://after-redirect.com')) {
+ ++testData.adBlockedCount;
+ }
+ });
+ apiObject[onAllowedEvent].addListener(function(e) {
+ if (e.url.includes('http://after-redirect.com')) {
+ ++testData.adAllowedCount;
+ }
+ });
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kReadCountersScript[] = R"(
+ chrome.test.sendScriptResult(
+ testData.adBlockedCount + '-' + testData.adAllowedCount);
+ )";
+
+ constexpr char kAddBlockingFilterScript[] = R"(
+ apiObject.addCustomFilter(%s'||after-redirect.com*/image.png');
+ chrome.test.sendScriptResult('');
+ )";
+
+ constexpr char kAddAllowingFilterScript[] = R"(
+ apiObject.addCustomFilter(%s'@@||after-redirect.com*/image.png');
+ chrome.test.sendScriptResult('');
+ )";
+
+ SetupApiObjectAndMethods(extension->id());
+
+ 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(), base::StringPrintf(kAddBlockingFilterScript,
+ IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ("1-0", ExecuteScriptInBackgroundPage(extension->id(),
+ kReadCountersScript));
+
+ // Allow and block filter
+ ExecuteScriptInBackgroundPage(
+ extension->id(), base::StringPrintf(kAddAllowingFilterScript,
+ IsOldApi() ? "" : "'adblock', "));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
+ ASSERT_EQ("1-1", ExecuteScriptInBackgroundPage(extension->id(),
+ kReadCountersScript));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ AdblockPrivateApiBackgroundPageTestWithRedirect,
+ testing::Combine(testing::Values(EyeoExtensionApi::Old,
+ EyeoExtensionApi::New),
+ testing::Values(Mode::Normal, Mode::Incognito)));
+
+} // 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"
@@ -15,6 +20,7 @@
#include "chrome/browser/extensions/api/cookies/cookies_api.h"
#include "chrome/browser/extensions/api/developer_private/developer_private_api.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
+#include "chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.h"
#include "chrome/browser/extensions/api/font_settings/font_settings_api.h"
#include "chrome/browser/extensions/api/history/history_api.h"
#include "chrome/browser/extensions/api/identity/identity_api.h"
@@ -73,6 +79,7 @@ namespace chrome_extensions {
void EnsureApiBrowserContextKeyedServiceFactoriesBuilt() {
extensions::ActivityLogAPI::GetFactoryInstance();
+ extensions::AdblockPrivateAPI::GetFactoryInstance();
extensions::AutofillPrivateEventRouterFactory::GetInstance();
extensions::BluetoothLowEnergyAPI::GetFactoryInstance();
extensions::BookmarksAPI::GetFactoryInstance();
@@ -82,6 +89,7 @@ void EnsureApiBrowserContextKeyedServiceFactoriesBuilt() {
extensions::CookiesAPI::GetFactoryInstance();
extensions::DeveloperPrivateAPI::GetFactoryInstance();
extensions::ExtensionActionAPI::GetFactoryInstance();
+ extensions::EyeoFilteringPrivateAPI::GetFactoryInstance();
extensions::FontSettingsAPI::GetFactoryInstance();
extensions::HistoryAPI::GetFactoryInstance();
extensions::IdentityAPI::GetFactoryInstance();
diff --git a/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.cc b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.cc
new file mode 100644
--- /dev/null
+++ b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.cc
@@ -0,0 +1,772 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#include "chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_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/resource_classification_runner_factory.h"
+#include "chrome/browser/adblock/session_stats_factory.h"
+#include "chrome/browser/adblock/subscription_service_factory.h"
+#include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/tabs.h"
+#include "components/adblock/content/browser/resource_classification_runner.h"
+#include "components/adblock/core/common/adblock_utils.h"
+#include "components/adblock/core/common/content_type.h"
+#include "components/adblock/core/configuration/filtering_configuration.h"
+#include "components/adblock/core/configuration/persistent_filtering_configuration.h"
+#include "components/adblock/core/session_stats.h"
+#include "components/adblock/core/subscription/subscription_config.h"
+#include "components/adblock/core/subscription/subscription_service.h"
+#include "components/prefs/pref_service.h"
+#include "components/sessions/core/session_id.h"
+#include "content/public/browser/web_contents.h"
+#include "url/gurl.h"
+namespace extensions {
+
+namespace {
+
+constexpr char kConfigurationMissing[] =
+ "Configuration with name '%s' does not exist!";
+
+adblock::FilteringConfiguration* FindFilteringConfiguration(
+ content::BrowserContext* context,
+ const std::string& config_name) {
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context);
+ const auto installed_configurations =
+ subscription_service->GetInstalledFilteringConfigurations();
+ auto configuration_it =
+ base::ranges::find(installed_configurations, config_name,
+ &adblock::FilteringConfiguration::GetName);
+ return configuration_it != installed_configurations.end() ? *configuration_it
+ : nullptr;
+}
+
+enum class SubscriptionAction { kInstall, kUninstall };
+
+std::string RunSubscriptionAction(
+ adblock::FilteringConfiguration* configuration,
+ SubscriptionAction action,
+ const GURL& url) {
+ if (!url.is_valid()) {
+ return "Invalid URL";
+ }
+ switch (action) {
+ case SubscriptionAction::kInstall:
+ configuration->AddFilterList(url);
+ break;
+ case SubscriptionAction::kUninstall:
+ configuration->RemoveFilterList(url);
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ return {};
+}
+
+std::vector<api::eyeo_filtering_private::SessionStatsEntry> CopySessionsStats(
+ const std::map<GURL, long>& source) {
+ std::vector<api::eyeo_filtering_private::SessionStatsEntry> result;
+ for (auto& entry : source) {
+ api::eyeo_filtering_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";
+ case State::Unknown:
+ return "Unknown";
+ }
+ NOTREACHED();
+ return "";
+}
+
+std::vector<api::eyeo_filtering_private::Subscription> CopySubscriptions(
+ const std::vector<scoped_refptr<adblock::Subscription>>
+ current_subscriptions) {
+ std::vector<api::eyeo_filtering_private::Subscription> result;
+ for (auto& sub : current_subscriptions) {
+ api::eyeo_filtering_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
+
+class EyeoFilteringPrivateAPI::EyeoFilteringAPIEventRouter
+ : public adblock::ResourceClassificationRunner::Observer,
+ public adblock::SubscriptionService::SubscriptionObserver,
+ public adblock::FilteringConfiguration::Observer {
+ public:
+ explicit EyeoFilteringAPIEventRouter(content::BrowserContext* context)
+ : context_(context) {
+ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context_)
+ ->AddObserver(this);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context_);
+ subscription_service->AddObserver(this);
+ for (auto* it :
+ subscription_service->GetInstalledFilteringConfigurations()) {
+ it->AddObserver(this);
+ }
+ }
+
+ ~EyeoFilteringAPIEventRouter() override {
+ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(context_)
+ ->RemoveObserver(this);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context_);
+ subscription_service->RemoveObserver(this);
+ for (auto* it :
+ subscription_service->GetInstalledFilteringConfigurations()) {
+ it->RemoveObserver(this);
+ }
+ }
+
+ // adblock::ResourceClassificationRunner::Observer:
+ void OnAdMatched(const GURL& url,
+ adblock::FilterMatchResult match_result,
+ const std::vector<GURL>& parent_frame_urls,
+ adblock::ContentType content_type,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& subscription,
+ const std::string& configuration_name) override {
+ std::unique_ptr<Event> event;
+ api::eyeo_filtering_private::RequestInfo info = CreateRequestInfoObject(
+ url, subscription, configuration_name, 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<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnRequestBlocked::kEventName,
+ api::eyeo_filtering_private::OnRequestBlocked::Create(info));
+ } else {
+ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule);
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnRequestAllowed::kEventName,
+ api::eyeo_filtering_private::OnRequestAllowed::Create(info));
+ }
+
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnPageAllowed(const GURL& url,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& subscription,
+ const std::string& configuration_name) override {
+ api::eyeo_filtering_private::RequestInfo info = CreateRequestInfoObject(
+ url, subscription, configuration_name, render_frame_host);
+ info.parent_frame_urls = std::vector<std::string>{};
+ info.content_type = "";
+
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnPageAllowed::kEventName,
+ api::eyeo_filtering_private::OnPageAllowed::Create(info));
+
+ 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,
+ const std::string& configuration_name) override {
+ std::unique_ptr<Event> event;
+ api::eyeo_filtering_private::RequestInfo info = CreateRequestInfoObject(
+ url, subscription, configuration_name, render_frame_host);
+ info.parent_frame_urls = std::vector<std::string>{opener_url.spec()};
+ info.content_type = "";
+
+ if (match_result == adblock::FilterMatchResult::kBlockRule) {
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnPopupBlocked::kEventName,
+ api::eyeo_filtering_private::OnPopupBlocked::Create(info));
+ } else {
+ DCHECK(match_result == adblock::FilterMatchResult::kAllowRule);
+ event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnPopupAllowed::kEventName,
+ api::eyeo_filtering_private::OnPopupAllowed::Create(info));
+ }
+
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ // adblock::SubscriptionService::SubscriptionObserver:
+ void OnSubscriptionInstalled(const GURL& url) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnSubscriptionUpdated::kEventName,
+ api::eyeo_filtering_private::OnSubscriptionUpdated::Create(url.spec()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnFilteringConfigurationInstalled(
+ adblock::FilteringConfiguration* config) override {
+ config->AddObserver(this);
+ }
+
+ // adblock::FilteringConfiguration::Observer:
+ void OnEnabledStateChanged(adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnEnabledStateChanged::kEventName,
+ api::eyeo_filtering_private::OnEnabledStateChanged::Create(
+ config->GetName()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnFilterListsChanged(adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnFilterListsChanged::kEventName,
+ api::eyeo_filtering_private::OnFilterListsChanged::Create(
+ config->GetName()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnAllowedDomainsChanged(
+ adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnAllowedDomainsChanged::kEventName,
+ api::eyeo_filtering_private::OnAllowedDomainsChanged::Create(
+ config->GetName()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ void OnCustomFiltersChanged(
+ adblock::FilteringConfiguration* config) override {
+ std::unique_ptr<Event> event = std::make_unique<Event>(
+ events::EYEO_EVENT,
+ api::eyeo_filtering_private::OnCustomFiltersChanged::kEventName,
+ api::eyeo_filtering_private::OnCustomFiltersChanged::Create(
+ config->GetName()));
+ extensions::EventRouter::Get(context_)->BroadcastEvent(std::move(event));
+ }
+
+ private:
+ api::eyeo_filtering_private::RequestInfo CreateRequestInfoObject(
+ const GURL& url,
+ const GURL& subscription,
+ const std::string& configuration_name,
+ content::RenderFrameHost* render_frame_host) {
+ DCHECK(render_frame_host);
+ api::eyeo_filtering_private::RequestInfo info;
+ info.url = url.spec();
+ info.subscription = subscription.spec();
+ info.configuration_name = configuration_name;
+ 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;
+ }
+
+ const raw_ptr<content::BrowserContext> context_;
+};
+
+template <>
+void BrowserContextKeyedAPIFactory<
+ EyeoFilteringPrivateAPI>::DeclareFactoryDependencies() {
+ DependsOn(adblock::SubscriptionServiceFactory::GetInstance());
+}
+
+// static
+BrowserContextKeyedAPIFactory<EyeoFilteringPrivateAPI>*
+EyeoFilteringPrivateAPI::GetFactoryInstance() {
+ static base::NoDestructor<
+ BrowserContextKeyedAPIFactory<EyeoFilteringPrivateAPI>>
+ instance;
+ return instance.get();
+}
+
+// static
+EyeoFilteringPrivateAPI* EyeoFilteringPrivateAPI::Get(
+ content::BrowserContext* context) {
+ return GetFactoryInstance()->Get(context);
+}
+
+EyeoFilteringPrivateAPI::EyeoFilteringPrivateAPI(
+ content::BrowserContext* context)
+ : context_(context) {
+ // EventRouter can be null in tests
+ auto* ev = EventRouter::Get(context_);
+ if (ev) {
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnRequestAllowed::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnRequestBlocked::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnPageAllowed::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnPopupAllowed::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnPopupBlocked::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnSubscriptionUpdated::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnEnabledStateChanged::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnFilterListsChanged::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnAllowedDomainsChanged::kEventName);
+ ev->RegisterObserver(
+ this, api::eyeo_filtering_private::OnCustomFiltersChanged::kEventName);
+ }
+ // Make sure SessionStats is created so it will start collectings stats
+ adblock::SessionStatsFactory::GetForBrowserContext(context);
+}
+
+EyeoFilteringPrivateAPI::~EyeoFilteringPrivateAPI() = default;
+
+void EyeoFilteringPrivateAPI::Shutdown() {
+ // EventRouter can be null in tests
+ if (EventRouter::Get(context_)) {
+ EventRouter::Get(context_)->UnregisterObserver(this);
+ }
+ event_router_.reset();
+}
+
+void EyeoFilteringPrivateAPI::OnListenerAdded(
+ const extensions::EventListenerInfo& details) {
+ event_router_ =
+ std::make_unique<EyeoFilteringPrivateAPI::EyeoFilteringAPIEventRouter>(
+ context_);
+ EventRouter::Get(context_)->UnregisterObserver(this);
+}
+
+namespace api {
+
+EyeoFilteringPrivateCreateConfigurationFunction::
+ EyeoFilteringPrivateCreateConfigurationFunction() = default;
+
+EyeoFilteringPrivateCreateConfigurationFunction::
+ ~EyeoFilteringPrivateCreateConfigurationFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateCreateConfigurationFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::CreateConfiguration::Params>
+ params(api::eyeo_filtering_private::CreateConfiguration::Params::Create(
+ args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context());
+ const auto installed_configurations =
+ subscription_service->GetInstalledFilteringConfigurations();
+ auto configuration_it =
+ base::ranges::find(installed_configurations, params->config_name,
+ &adblock::FilteringConfiguration::GetName);
+ if (configuration_it == installed_configurations.end()) {
+ auto new_filtering_configuration =
+ std::make_unique<adblock::PersistentFilteringConfiguration>(
+ Profile::FromBrowserContext(browser_context())
+ ->GetOriginalProfile()
+ ->GetPrefs(),
+ params->config_name);
+ subscription_service->InstallFilteringConfiguration(
+ std::move(new_filtering_configuration));
+ }
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateRemoveConfigurationFunction::
+ EyeoFilteringPrivateRemoveConfigurationFunction() = default;
+
+EyeoFilteringPrivateRemoveConfigurationFunction::
+ ~EyeoFilteringPrivateRemoveConfigurationFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateRemoveConfigurationFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::RemoveConfiguration::Params>
+ params(api::eyeo_filtering_private::RemoveConfiguration::Params::Create(
+ args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context());
+ const auto installed_configurations =
+ subscription_service->GetInstalledFilteringConfigurations();
+ auto configuration_it =
+ base::ranges::find(installed_configurations, params->config_name,
+ &adblock::FilteringConfiguration::GetName);
+ if (configuration_it != installed_configurations.end()) {
+ subscription_service->UninstallFilteringConfiguration(
+ (*configuration_it)->GetName());
+ }
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateGetConfigurationsFunction::
+ EyeoFilteringPrivateGetConfigurationsFunction() = default;
+
+EyeoFilteringPrivateGetConfigurationsFunction::
+ ~EyeoFilteringPrivateGetConfigurationsFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetConfigurationsFunction::Run() {
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context());
+ const auto installed_configurations =
+ subscription_service->GetInstalledFilteringConfigurations();
+ std::vector<std::string> configurations;
+ base::ranges::transform(installed_configurations,
+ std::back_inserter(configurations),
+ [](adblock::FilteringConfiguration* config) {
+ return config->GetName();
+ });
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetConfigurations::Results::Create(
+ std::move(configurations))));
+}
+
+EyeoFilteringPrivateSetEnabledFunction::
+ EyeoFilteringPrivateSetEnabledFunction() = default;
+
+EyeoFilteringPrivateSetEnabledFunction::
+ ~EyeoFilteringPrivateSetEnabledFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateSetEnabledFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::SetEnabled::Params> params(
+ api::eyeo_filtering_private::SetEnabled::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ configuration->SetEnabled(params->enabled);
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateIsEnabledFunction::EyeoFilteringPrivateIsEnabledFunction() {
+}
+
+EyeoFilteringPrivateIsEnabledFunction::
+ ~EyeoFilteringPrivateIsEnabledFunction() = default;
+
+ExtensionFunction::ResponseAction EyeoFilteringPrivateIsEnabledFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::IsEnabled::Params> params(
+ api::eyeo_filtering_private::IsEnabled::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ return RespondNow(
+ ArgumentList(api::eyeo_filtering_private::IsEnabled::Results::Create(
+ configuration->IsEnabled())));
+}
+
+EyeoFilteringPrivateGetAcceptableAdsUrlFunction::
+ EyeoFilteringPrivateGetAcceptableAdsUrlFunction() = default;
+
+EyeoFilteringPrivateGetAcceptableAdsUrlFunction::
+ ~EyeoFilteringPrivateGetAcceptableAdsUrlFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetAcceptableAdsUrlFunction::Run() {
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetAcceptableAdsUrl::Results::Create(
+ adblock::AcceptableAdsUrl().spec())));
+}
+
+EyeoFilteringPrivateSubscribeToFilterListFunction::
+ EyeoFilteringPrivateSubscribeToFilterListFunction() = default;
+
+EyeoFilteringPrivateSubscribeToFilterListFunction::
+ ~EyeoFilteringPrivateSubscribeToFilterListFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateSubscribeToFilterListFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::SubscribeToFilterList::Params>
+ params(api::eyeo_filtering_private::SubscribeToFilterList::Params::Create(
+ args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ auto url = GURL{params->url};
+ auto status =
+ RunSubscriptionAction(configuration, SubscriptionAction::kInstall, url);
+ if (!status.empty()) {
+ return RespondNow(Error(status));
+ }
+
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateUnsubscribeFromFilterListFunction::
+ EyeoFilteringPrivateUnsubscribeFromFilterListFunction() = default;
+
+EyeoFilteringPrivateUnsubscribeFromFilterListFunction::
+ ~EyeoFilteringPrivateUnsubscribeFromFilterListFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateUnsubscribeFromFilterListFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::UnsubscribeFromFilterList::Params>
+ params(api::eyeo_filtering_private::UnsubscribeFromFilterList::Params::
+ Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ auto url = GURL{params->url};
+ auto status =
+ RunSubscriptionAction(configuration, SubscriptionAction::kUninstall, url);
+ if (!status.empty()) {
+ return RespondNow(Error(status));
+ }
+
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateGetFilterListsFunction::
+ EyeoFilteringPrivateGetFilterListsFunction() = default;
+
+EyeoFilteringPrivateGetFilterListsFunction::
+ ~EyeoFilteringPrivateGetFilterListsFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetFilterListsFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::GetFilterLists::Params> params(
+ api::eyeo_filtering_private::GetFilterLists::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ auto* subscription_service =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser_context());
+ return RespondNow(
+ ArgumentList(api::eyeo_filtering_private::GetFilterLists::Results::Create(
+ CopySubscriptions(
+ subscription_service->GetCurrentSubscriptions(configuration)))));
+}
+
+EyeoFilteringPrivateAddAllowedDomainFunction::
+ EyeoFilteringPrivateAddAllowedDomainFunction() = default;
+
+EyeoFilteringPrivateAddAllowedDomainFunction::
+ ~EyeoFilteringPrivateAddAllowedDomainFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateAddAllowedDomainFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::AddAllowedDomain::Params> params(
+ api::eyeo_filtering_private::AddAllowedDomain::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ configuration->AddAllowedDomain(params->domain);
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateRemoveAllowedDomainFunction::
+ EyeoFilteringPrivateRemoveAllowedDomainFunction() = default;
+
+EyeoFilteringPrivateRemoveAllowedDomainFunction::
+ ~EyeoFilteringPrivateRemoveAllowedDomainFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateRemoveAllowedDomainFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::RemoveAllowedDomain::Params>
+ params(api::eyeo_filtering_private::RemoveAllowedDomain::Params::Create(
+ args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ configuration->RemoveAllowedDomain(params->domain);
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateGetAllowedDomainsFunction::
+ EyeoFilteringPrivateGetAllowedDomainsFunction() = default;
+
+EyeoFilteringPrivateGetAllowedDomainsFunction::
+ ~EyeoFilteringPrivateGetAllowedDomainsFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetAllowedDomainsFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::GetAllowedDomains::Params> params(
+ api::eyeo_filtering_private::GetAllowedDomains::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetCustomFilters::Results::Create(
+ configuration->GetAllowedDomains())));
+}
+
+EyeoFilteringPrivateAddCustomFilterFunction::
+ EyeoFilteringPrivateAddCustomFilterFunction() = default;
+
+EyeoFilteringPrivateAddCustomFilterFunction::
+ ~EyeoFilteringPrivateAddCustomFilterFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateAddCustomFilterFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::AddCustomFilter::Params> params(
+ api::eyeo_filtering_private::AddCustomFilter::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ configuration->AddCustomFilter(params->filter);
+ return RespondNow(NoArguments());
+}
+
+EyeoFilteringPrivateRemoveCustomFilterFunction::
+ EyeoFilteringPrivateRemoveCustomFilterFunction() = default;
+
+EyeoFilteringPrivateRemoveCustomFilterFunction::
+ ~EyeoFilteringPrivateRemoveCustomFilterFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateRemoveCustomFilterFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::RemoveCustomFilter::Params>
+ params(api::eyeo_filtering_private::RemoveCustomFilter::Params::Create(
+ args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ configuration->RemoveCustomFilter(params->filter);
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetCustomFiltersFunction::Run() {
+ absl::optional<api::eyeo_filtering_private::GetCustomFilters::Params> params(
+ api::eyeo_filtering_private::GetCustomFilters::Params::Create(args()));
+ EXTENSION_FUNCTION_VALIDATE(params);
+ auto* configuration =
+ FindFilteringConfiguration(browser_context(), params->configuration);
+ if (!configuration) {
+ return RespondNow(Error(base::StringPrintf(kConfigurationMissing,
+ params->configuration.c_str())));
+ }
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetCustomFilters::Results::Create(
+ configuration->GetCustomFilters())));
+}
+
+EyeoFilteringPrivateGetCustomFiltersFunction::
+ EyeoFilteringPrivateGetCustomFiltersFunction() = default;
+
+EyeoFilteringPrivateGetCustomFiltersFunction::
+ ~EyeoFilteringPrivateGetCustomFiltersFunction() = default;
+
+EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction::
+ EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction() = default;
+
+EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction::
+ ~EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction::Run() {
+ auto* session_stats =
+ adblock::SessionStatsFactory::GetForBrowserContext(browser_context());
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetSessionAllowedRequestsCount::Results::
+ Create(
+ CopySessionsStats(session_stats->GetSessionAllowedAdsCount()))));
+}
+
+EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction::
+ EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction() = default;
+
+EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction::
+ ~EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction() = default;
+
+ExtensionFunction::ResponseAction
+EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction::Run() {
+ auto* session_stats =
+ adblock::SessionStatsFactory::GetForBrowserContext(browser_context());
+ return RespondNow(ArgumentList(
+ api::eyeo_filtering_private::GetSessionBlockedRequestsCount::Results::
+ Create(
+ CopySessionsStats(session_stats->GetSessionBlockedAdsCount()))));
+}
+} // namespace api
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.h b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.h
new file mode 100644
--- /dev/null
+++ b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_api.h
@@ -0,0 +1,360 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_EYEO_FILTERING_PRIVATE_EYEO_FILTERING_PRIVATE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_EYEO_FILTERING_PRIVATE_EYEO_FILTERING_PRIVATE_API_H_
+
+#include "base/memory/raw_ptr.h"
+#include "chrome/common/extensions/api/eyeo_filtering_private.h"
+#include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_function.h"
+
+namespace extensions {
+
+class EyeoFilteringPrivateAPI : public BrowserContextKeyedAPI,
+ public EventRouter::Observer {
+ public:
+ static BrowserContextKeyedAPIFactory<EyeoFilteringPrivateAPI>*
+ GetFactoryInstance();
+
+ static EyeoFilteringPrivateAPI* Get(content::BrowserContext* context);
+
+ explicit EyeoFilteringPrivateAPI(content::BrowserContext* context);
+ ~EyeoFilteringPrivateAPI() override;
+ friend class BrowserContextKeyedAPIFactory<EyeoFilteringPrivateAPI>;
+
+ // BrowserContextKeyedAPI implementation.
+ static const char* service_name() { return "EyeoFilteringPrivateAPI"; }
+ static const bool kServiceRedirectedInIncognito = true;
+ static const bool kServiceIsCreatedWithBrowserContext = true;
+ void Shutdown() override;
+
+ // EventRouter::Observer:
+ void OnListenerAdded(const extensions::EventListenerInfo& details) override;
+
+ private:
+ const raw_ptr<content::BrowserContext> context_;
+ class EyeoFilteringAPIEventRouter;
+ std::unique_ptr<EyeoFilteringAPIEventRouter> event_router_;
+};
+
+template <>
+void BrowserContextKeyedAPIFactory<
+ EyeoFilteringPrivateAPI>::DeclareFactoryDependencies();
+
+namespace api {
+
+class EyeoFilteringPrivateCreateConfigurationFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.createConfiguration",
+ UNKNOWN)
+ EyeoFilteringPrivateCreateConfigurationFunction();
+
+ private:
+ ~EyeoFilteringPrivateCreateConfigurationFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateCreateConfigurationFunction(
+ const EyeoFilteringPrivateCreateConfigurationFunction&) = delete;
+ EyeoFilteringPrivateCreateConfigurationFunction& operator=(
+ const EyeoFilteringPrivateCreateConfigurationFunction&) = delete;
+};
+
+class EyeoFilteringPrivateRemoveConfigurationFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.removeConfiguration",
+ UNKNOWN)
+ EyeoFilteringPrivateRemoveConfigurationFunction();
+
+ private:
+ ~EyeoFilteringPrivateRemoveConfigurationFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateRemoveConfigurationFunction(
+ const EyeoFilteringPrivateRemoveConfigurationFunction&) = delete;
+ EyeoFilteringPrivateRemoveConfigurationFunction& operator=(
+ const EyeoFilteringPrivateRemoveConfigurationFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetConfigurationsFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.getConfigurations", UNKNOWN)
+ EyeoFilteringPrivateGetConfigurationsFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetConfigurationsFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetConfigurationsFunction(
+ const EyeoFilteringPrivateGetConfigurationsFunction&) = delete;
+ EyeoFilteringPrivateGetConfigurationsFunction& operator=(
+ const EyeoFilteringPrivateGetConfigurationsFunction&) = delete;
+};
+
+class EyeoFilteringPrivateSetEnabledFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.setEnabled", UNKNOWN)
+ EyeoFilteringPrivateSetEnabledFunction();
+
+ private:
+ ~EyeoFilteringPrivateSetEnabledFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateSetEnabledFunction(
+ const EyeoFilteringPrivateSetEnabledFunction&) = delete;
+ EyeoFilteringPrivateSetEnabledFunction& operator=(
+ const EyeoFilteringPrivateSetEnabledFunction&) = delete;
+};
+
+class EyeoFilteringPrivateIsEnabledFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.isEnabled", UNKNOWN)
+ EyeoFilteringPrivateIsEnabledFunction();
+
+ private:
+ ~EyeoFilteringPrivateIsEnabledFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateIsEnabledFunction(
+ const EyeoFilteringPrivateIsEnabledFunction&) = delete;
+ EyeoFilteringPrivateIsEnabledFunction& operator=(
+ const EyeoFilteringPrivateIsEnabledFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetAcceptableAdsUrlFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.getAcceptableAdsUrl",
+ UNKNOWN)
+ EyeoFilteringPrivateGetAcceptableAdsUrlFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetAcceptableAdsUrlFunction() override;
+
+ // ExtensionFunction:
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetAcceptableAdsUrlFunction(
+ const EyeoFilteringPrivateGetAcceptableAdsUrlFunction&) = delete;
+ EyeoFilteringPrivateGetAcceptableAdsUrlFunction& operator=(
+ const EyeoFilteringPrivateGetAcceptableAdsUrlFunction&) = delete;
+};
+
+class EyeoFilteringPrivateSubscribeToFilterListFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.subscribeToFilterList",
+ UNKNOWN)
+ EyeoFilteringPrivateSubscribeToFilterListFunction();
+
+ private:
+ ~EyeoFilteringPrivateSubscribeToFilterListFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateSubscribeToFilterListFunction(
+ const EyeoFilteringPrivateSubscribeToFilterListFunction&) = delete;
+ EyeoFilteringPrivateSubscribeToFilterListFunction& operator=(
+ const EyeoFilteringPrivateSubscribeToFilterListFunction&) = delete;
+};
+
+class EyeoFilteringPrivateUnsubscribeFromFilterListFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.unsubscribeFromFilterList",
+ UNKNOWN)
+ EyeoFilteringPrivateUnsubscribeFromFilterListFunction();
+
+ private:
+ ~EyeoFilteringPrivateUnsubscribeFromFilterListFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateUnsubscribeFromFilterListFunction(
+ const EyeoFilteringPrivateUnsubscribeFromFilterListFunction&) = delete;
+ EyeoFilteringPrivateUnsubscribeFromFilterListFunction& operator=(
+ const EyeoFilteringPrivateUnsubscribeFromFilterListFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetFilterListsFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.getFilterLists", UNKNOWN)
+ EyeoFilteringPrivateGetFilterListsFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetFilterListsFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetFilterListsFunction(
+ const EyeoFilteringPrivateGetFilterListsFunction&) = delete;
+ EyeoFilteringPrivateGetFilterListsFunction& operator=(
+ const EyeoFilteringPrivateGetFilterListsFunction&) = delete;
+};
+
+class EyeoFilteringPrivateAddAllowedDomainFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.addAllowedDomain", UNKNOWN)
+ EyeoFilteringPrivateAddAllowedDomainFunction();
+
+ private:
+ ~EyeoFilteringPrivateAddAllowedDomainFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateAddAllowedDomainFunction(
+ const EyeoFilteringPrivateAddAllowedDomainFunction&) = delete;
+ EyeoFilteringPrivateAddAllowedDomainFunction& operator=(
+ const EyeoFilteringPrivateAddAllowedDomainFunction&) = delete;
+};
+
+class EyeoFilteringPrivateRemoveAllowedDomainFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.removeAllowedDomain",
+ UNKNOWN)
+ EyeoFilteringPrivateRemoveAllowedDomainFunction();
+
+ private:
+ ~EyeoFilteringPrivateRemoveAllowedDomainFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateRemoveAllowedDomainFunction(
+ const EyeoFilteringPrivateRemoveAllowedDomainFunction&) = delete;
+ EyeoFilteringPrivateRemoveAllowedDomainFunction& operator=(
+ const EyeoFilteringPrivateRemoveAllowedDomainFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetAllowedDomainsFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.getAllowedDomains", UNKNOWN)
+ EyeoFilteringPrivateGetAllowedDomainsFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetAllowedDomainsFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetAllowedDomainsFunction(
+ const EyeoFilteringPrivateGetAllowedDomainsFunction&) = delete;
+ EyeoFilteringPrivateGetAllowedDomainsFunction& operator=(
+ const EyeoFilteringPrivateGetAllowedDomainsFunction&) = delete;
+};
+
+class EyeoFilteringPrivateAddCustomFilterFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.addCustomFilter", UNKNOWN)
+ EyeoFilteringPrivateAddCustomFilterFunction();
+
+ private:
+ ~EyeoFilteringPrivateAddCustomFilterFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateAddCustomFilterFunction(
+ const EyeoFilteringPrivateAddCustomFilterFunction&) = delete;
+ EyeoFilteringPrivateAddCustomFilterFunction& operator=(
+ const EyeoFilteringPrivateAddCustomFilterFunction&) = delete;
+};
+
+class EyeoFilteringPrivateRemoveCustomFilterFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.removeCustomFilter", UNKNOWN)
+ EyeoFilteringPrivateRemoveCustomFilterFunction();
+
+ private:
+ ~EyeoFilteringPrivateRemoveCustomFilterFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateRemoveCustomFilterFunction(
+ const EyeoFilteringPrivateRemoveCustomFilterFunction&) = delete;
+ EyeoFilteringPrivateRemoveCustomFilterFunction& operator=(
+ const EyeoFilteringPrivateRemoveCustomFilterFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetCustomFiltersFunction : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("eyeoFilteringPrivate.getCustomFilters", UNKNOWN)
+ EyeoFilteringPrivateGetCustomFiltersFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetCustomFiltersFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetCustomFiltersFunction(
+ const EyeoFilteringPrivateGetCustomFiltersFunction&) = delete;
+ EyeoFilteringPrivateGetCustomFiltersFunction& operator=(
+ const EyeoFilteringPrivateGetCustomFiltersFunction&) = delete;
+};
+
+class EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION(
+ "eyeoFilteringPrivate.getSessionAllowedRequestsCount",
+ UNKNOWN)
+ EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction(
+ const EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction&) =
+ delete;
+ EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction& operator=(
+ const EyeoFilteringPrivateGetSessionAllowedRequestsCountFunction&) =
+ delete;
+};
+
+class EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction
+ : public ExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION(
+ "eyeoFilteringPrivate.getSessionBlockedRequestsCount",
+ UNKNOWN)
+ EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction();
+
+ private:
+ ~EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction() override;
+
+ ResponseAction Run() override;
+
+ EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction(
+ const EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction&) =
+ delete;
+ EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction& operator=(
+ const EyeoFilteringPrivateGetSessionBlockedRequestsCountFunction&) =
+ delete;
+};
+
+} // namespace api
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_EYEO_FILTERING_PRIVATE_EYEO_FILTERING_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_apitest.cc b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_apitest.cc
new file mode 100644
--- /dev/null
+++ b/chrome/browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_apitest.cc
@@ -0,0 +1,161 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#include "chrome/browser/adblock/adblock_content_browser_client.h"
+#include "chrome/browser/adblock/subscription_service_factory.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/api/adblock_private.h"
+#include "components/adblock/core/adblock_controller.h"
+#include "components/adblock/core/common/adblock_constants.h"
+#include "components/adblock/core/subscription/subscription_service.h"
+#include "content/public/test/browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace {
+enum class Mode { Normal, Incognito };
+} // namespace
+
+class EyeoFilteringPrivateApiTest : public ExtensionApiTest,
+ public testing::WithParamInterface<Mode> {
+ public:
+ EyeoFilteringPrivateApiTest() {}
+ ~EyeoFilteringPrivateApiTest() override = default;
+ EyeoFilteringPrivateApiTest(const EyeoFilteringPrivateApiTest&) = delete;
+ EyeoFilteringPrivateApiTest& operator=(const EyeoFilteringPrivateApiTest&) =
+ delete;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
+ if (IsIncognito()) {
+ command_line->AppendSwitch(switches::kIncognito);
+ }
+ }
+
+ protected:
+ void SetUpOnMainThread() override {
+ ExtensionApiTest::SetUpOnMainThread();
+
+ auto* adblock_configuration =
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
+ browser()->profile())
+ ->GetAdblockFilteringConfiguration();
+ if (adblock_configuration) {
+ adblock_configuration->RemoveCustomFilter(
+ adblock::kAllowlistEverythingFilter);
+ }
+
+ AdblockContentBrowserClient::ForceAdblockProxyForTesting();
+ }
+
+ bool IsIncognito() { return GetParam() == Mode::Incognito; }
+
+ bool RunTest(const std::string& subtest) {
+ const std::string page_url = "main.html?subtest=" + subtest;
+ return RunExtensionTest("eyeo_filtering_private",
+ {.extension_url = page_url.c_str()},
+ {.allow_in_incognito = IsIncognito(),
+ .load_as_component = !IsIncognito()});
+ }
+};
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ CreateRemoveAndGetConfigurations) {
+ EXPECT_TRUE(RunTest("createRemoveAndGetConfigurations")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ CreateRemoveAndGetConfigurationsWithPromises) {
+ EXPECT_TRUE(RunTest("createRemoveAndGetConfigurationsWithPromises"))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ EnableAndDisableConfiguration) {
+ EXPECT_TRUE(RunTest("enableAndDisableConfiguration")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ EnableAndDisableConfigurationWithPromises) {
+ EXPECT_TRUE(RunTest("enableAndDisableConfigurationWithPromises")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ AddAllowedDomainToCustomConfiguration) {
+ EXPECT_TRUE(RunTest("addAllowedDomainToCustomConfiguration")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ AddAllowedDomainToCustomConfigurationWithPromises) {
+ EXPECT_TRUE(RunTest("addAllowedDomainToCustomConfigurationWithPromises"))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ AddCustomFilterToCustomConfiguration) {
+ EXPECT_TRUE(RunTest("addCustomFilterToCustomConfiguration")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ AddCustomFilterToCustomConfigurationWithPromises) {
+ EXPECT_TRUE(RunTest("addCustomFilterToCustomConfigurationWithPromises"))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ SubscribeToFilterListInCustomConfiguration) {
+ EXPECT_TRUE(RunTest("subscribeToFilterListInCustomConfiguration"))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ SubscribeToFilterListInCustomConfigurationWithPromises) {
+ EXPECT_TRUE(RunTest("subscribeToFilterListInCustomConfigurationWithPromises"))
+ << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest, MissingConfiguration) {
+ EXPECT_TRUE(RunTest("missingConfiguration")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest,
+ MissingConfigurationWithPromises) {
+ EXPECT_TRUE(RunTest("missingConfigurationWithPromises")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest, AllowedDomainsEvent) {
+ EXPECT_TRUE(RunTest("allowedDomainsEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest, EnabledStateEvent) {
+ EXPECT_TRUE(RunTest("enabledStateEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest, FilterListsEvent) {
+ EXPECT_TRUE(RunTest("filterListsEvent")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(EyeoFilteringPrivateApiTest, CustomFiltersEvent) {
+ EXPECT_TRUE(RunTest("customFiltersEvent")) << message_;
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+ EyeoFilteringPrivateApiTest,
+ testing::Values(Mode::Normal, Mode::Incognito));
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This source code is a part of eyeo Chromium SDK.
+// Use of this source code is governed by the GPLv3 that can be found in the
+// components/adblock/LICENSE file.
+
#include "chrome/browser/extensions/api/settings_private/prefs_util.h"
#include <memory>
@@ -27,6 +31,7 @@
#include "chrome/browser/ssl/generated_https_first_mode_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"
@@ -173,6 +178,20 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() {
return *s_allowlist;
s_allowlist = new PrefsUtil::TypedPrefMap();
+ // Adblock settings
+ (*s_allowlist)[adblock::common::prefs::kEnableAdblockLegacy] =
+ settings_api::PrefType::PREF_TYPE_BOOLEAN;
+ (*s_allowlist)[adblock::common::prefs::kEnableAcceptableAdsLegacy] =
+ settings_api::PrefType::PREF_TYPE_BOOLEAN;
+ (*s_allowlist)[adblock::common::prefs::kAdblockSubscriptionsLegacy] =
+ settings_api::PrefType::PREF_TYPE_LIST;
+ (*s_allowlist)[adblock::common::prefs::kAdblockCustomSubscriptionsLegacy] =
+ settings_api::PrefType::PREF_TYPE_LIST;
+ (*s_allowlist)[adblock::common::prefs::kAdblockAllowedDomainsLegacy] =
+ settings_api::PrefType::PREF_TYPE_LIST;
+ (*s_allowlist)[adblock::common::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/extensions/extension_function_registration_test.cc b/chrome/browser/extensions/extension_function_registration_test.cc
--- a/chrome/browser/extensions/extension_function_registration_test.cc
+++ b/chrome/browser/extensions/extension_function_registration_test.cc
@@ -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.
#include "base/one_shot_event.h"
#include "chrome/browser/extensions/extension_browsertest.h"
@@ -56,6 +60,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionFunctionRegistrationTest,
base::CompareCase::SENSITIVE)) {
continue;
}
+ // Eyeo extension API uses UNKNOWN; it's not used in histograms.
+ if (base::StartsWith(entry.function_name_, "adblockPrivate.") ||
+ base::StartsWith(entry.function_name_, "eyeoFilteringPrivate.")) {
+ continue;
+ }
+
// Some undocumented, unlaunched APIs may also use UNKNOWN if it's unclear
// (or unlikely) if they will ever launch.
if (base::Contains(kAllowedUnknownHistogramEntries,
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -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.
+
// This features file defines extension APIs implemented under src/chrome.
// See chrome/common/extensions/api/_features.md to understand this file, as
@@ -95,6 +99,16 @@
"chrome://extensions/*"
]
}],
+ "adblockPrivate": [{
+ "dependencies": ["permission:adblockPrivate"],
+ "contexts": ["blessed_extension"]
+ }, {
+ "channel": "stable",
+ "contexts": ["webui"],
+ "matches": [
+ "chrome://settings/*"
+ ]
+ }],
"app": {
"blocklist": [
"2FC374607C2DF285634B67C64A2E356C607091C3", // Quickoffice
@@ -497,6 +511,14 @@
"channel": "stable",
"contexts": []
},
+ "eyeoFilteringPrivate": [{
+ "dependencies": ["permission:eyeoFilteringPrivate"],
+ "contexts": ["blessed_extension"]
+ }, {
+ "channel": "stable",
+ "contexts": ["webui"],
+ "matches": ["chrome://settings/*"]
+ }],
"fileBrowserHandler": {
"dependencies": ["permission:fileBrowserHandler"],
"contexts": ["blessed_extension"],
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -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.
+
// This features file defines permissions for extension APIs implemented
// under src/chrome.
@@ -56,6 +60,10 @@
"5107DE9024C329EEA9C9A72D94C16723790C6422" // Apps Developer Tool Dev.
]
},
+ "adblockPrivate": {
+ "channel": "stable",
+ "extension_types": ["extension", "platform_app"]
+ },
"autofillPrivate": {
"channel": "trunk",
"extension_types": ["extension", "platform_app"],
@@ -343,6 +351,10 @@
"extension", "legacy_packaged_app", "hosted_app", "platform_app"
]
},
+ "eyeoFilteringPrivate": {
+ "channel": "stable",
+ "extension_types": ["extension", "platform_app"]
+ },
"favicon": {
"channel": "stable",
"extension_types": ["extension"]
diff --git a/chrome/common/extensions/api/adblock_private.idl b/chrome/common/extensions/api/adblock_private.idl
new file mode 100644
--- /dev/null
+++ b/chrome/common/extensions/api/adblock_private.idl
@@ -0,0 +1,174 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+// DEPRECATED: Prefer eyeoFilteringPrivate.
+// adblockPrivate API.
+// This is a private API exposing ability to control AdblockPlus.
+//
+// Devs: when modifying this file, ensure you update
+// tools/typescript/definitions/adblock_private.d.ts as well.
+// See DPD-1870 for more information.
+namespace adblockPrivate {
+
+dictionary BuiltInSubscription {
+ // Subscription url
+ DOMString url;
+ // Subscription title (may be empty)
+ DOMString title;
+ // list of languages this subscription is relevant for.
+ DOMString[] languages;
+};
+
+dictionary Subscription {
+ // Subscription url
+ DOMString url;
+ // Current state of the subscription. Allowed values are:
+ // "Installed"
+ // "Preloaded"
+ // "Installing"
+ // See components/adblock/core/subscription/subscription.h for description.
+ DOMString installation_state;
+ // Subscription title (may be empty)
+ DOMString title;
+ // Subscription version (may be empty)
+ DOMString current_version;
+ // Time of last successful installation or update, in ISO 8601 format.
+ // May be passed directly to the Date constructor.
+ DOMString last_installation_time;
+};
+
+dictionary SessionStatsEntry {
+ // Subscription url or "adblock:custom" when custom filter was matched
+ DOMString url;
+ // Subscription hits
+ long count;
+};
+
+dictionary AdInfo {
+ // URL of the ad element which has been matched.
+ DOMString url;
+ // URLs of the parent frames.
+ DOMString[] parent_frame_urls;
+ // URL of subscription having the filter which matched for the ad.
+ DOMString subscription;
+ // Configuration name containing subscription with matched filer.
+ DOMString configuration_name;
+ // A string representation of matched ad's resource type.
+ // Possible values are:
+ // - "SCRIPT"
+ // - "IMAGE"
+ // - "STYLESHEET"
+ // - "OBJECT"
+ // - "SUBDOCUMENT"
+ // - "WEBSOCKET"
+ // - "WEBRTC"
+ // - "PING"
+ // - "XMLHTTPREQUEST"
+ // - "MEDIA"
+ // - "FONT"
+ // - "OTHER" (when none of the above matches)
+ // See: components/adblock/core/common/content_type.h
+ DOMString content_type;
+ // Tab id for which the event is fired. Defaults to -1, a numerical value of
+ // api::tabs::TAB_ID_NONE which means tab id cannot be obtained.
+ long tab_id;
+ // Window id for which the event is fired. Defaults to -1 which is a value
+ // of SessionID::InvalidValue() which means window id cannot be obtained.
+ long window_id;
+};
+
+callback BuiltInSubscriptionsCallback = void(BuiltInSubscription[] result);
+callback SubscriptionsCallback = void(Subscription[] result);
+callback StateCallback = void(boolean result);
+callback CompletionCallback = void();
+callback ListCallback = void(DOMString[] result);
+callback SessionStatsCallback = void(SessionStatsEntry[] result);
+
+interface Functions {
+ // Allows to turn Adblock on or off.
+ static void setEnabled(boolean enabled);
+ // Returns whether Adblock is on.
+ static void isEnabled(StateCallback callback);
+ // Allows to turn Acceptable Ads on or off.
+ static void setAcceptableAdsEnabled(boolean enabled);
+ // Returns whether Acceptable Ads is on.
+ static void isAcceptableAdsEnabled(StateCallback callback);
+ // Gets the list of built-in subscriptions.
+ static void getBuiltInSubscriptions(BuiltInSubscriptionsCallback callback);
+ // Adds a domain ads should not be blocked on.
+ static void addAllowedDomain(DOMString domain);
+ // Removes a domain ads should not be blocked on.
+ static void removeAllowedDomain(DOMString domain);
+ // Returns a list of domains ads are not blocked on.
+ static void getAllowedDomains(ListCallback callback);
+ // Adds a custom filter.
+ static void addCustomFilter(DOMString filter);
+ // Removes a custom filter.
+ static void removeCustomFilter(DOMString filter);
+ // Returns a list of custom filters a user set.
+ static void getCustomFilters(ListCallback callback);
+ // Returns number of allowlisted requests in a current session (runtime).
+ static void getSessionAllowedAdsCount(SessionStatsCallback callback);
+ // Returns number of blocked requests in a current session (runtime).
+ static void getSessionBlockedAdsCount(SessionStatsCallback callback);
+ // Compiles a list of currently installed subscriptions. Filter lists that are
+ // still being installed and don't yet participate in ad filtering also appear
+ // on this list and can be discerned by their installation_state.
+ static void getInstalledSubscriptions(SubscriptionsCallback callback);
+ // Subscribes to a filter list. If subscription was already done and not
+ // removed later by "uninstallSubscription()" call then this is a no-op call,
+ // otherwise it initiates a download. |url| must point to a https URL.
+ static void installSubscription(DOMString url,
+ optional CompletionCallback feedback);
+ // Removes a subscription to a filter list downloaded from |url| and deletes
+ // corresponding files from disk. Does nothing if the filter list was never
+ // subscribed to.
+ static void uninstallSubscription(DOMString url,
+ optional CompletionCallback feedback);
+};
+
+interface Events {
+ // Fired when an ad is explicitly allowed by an exception rule.
+ static void onAdAllowed(AdInfo info);
+
+ // Fired when an ad is blocked.
+ static void onAdBlocked(AdInfo info);
+
+ // Fired when a whole page is allowlisted.
+ static void onPageAllowed(AdInfo info);
+
+ // Fired when a popup is blocked.
+ static void onPopupBlocked(AdInfo info);
+
+ // Fired when a popup is allowlisted.
+ static void onPopupAllowed(AdInfo info);
+
+ // Fired when a subscription has been updated.
+ static void onSubscriptionUpdated(DOMString subscription_url);
+
+ // Fired when ad-filtering enable state changed
+ static void onEnabledStateChanged();
+
+ // Fired when subscription added or removed.
+ static void onFilterListsChanged();
+
+ // Fired when allowed domain list has been updated.
+ static void onAllowedDomainsChanged();
+
+ // Fired when custom filter added or removed.
+ static void onCustomFiltersChanged();
+};
+
+};
diff --git a/chrome/common/extensions/api/api_sources.gni b/chrome/common/extensions/api/api_sources.gni
--- a/chrome/common/extensions/api/api_sources.gni
+++ b/chrome/common/extensions/api/api_sources.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("//build/config/chromeos/ui_mode.gni")
import("//build/config/features.gni")
@@ -12,6 +16,7 @@ assert(enable_extensions)
schema_sources_ = [
"accessibility_features.json",
"activity_log_private.json",
+ "adblock_private.idl",
"autofill_private.idl",
"autotest_private.idl",
"bookmark_manager_private.json",
@@ -31,6 +36,7 @@ schema_sources_ = [
"downloads_internal.idl",
"enterprise_hardware_platform.idl",
"enterprise_reporting_private.idl",
+ "eyeo_filtering_private.idl",
"font_settings.json",
"gcm.json",
"history.json",
diff --git a/chrome/common/extensions/api/eyeo_filtering_private.idl b/chrome/common/extensions/api/eyeo_filtering_private.idl
new file mode 100644
--- /dev/null
+++ b/chrome/common/extensions/api/eyeo_filtering_private.idl
@@ -0,0 +1,201 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+// eyeoFilteringPrivate API.
+// This is a private API exposing control over resource filtering.
+//
+// Devs: when modifying this file, ensure you update
+// tools/typescript/definitions/eyeo_filtering_private.d.ts as well.
+// See DPD-1870 for more information.
+namespace eyeoFilteringPrivate {
+
+ dictionary Subscription {
+ // Subscription url
+ DOMString url;
+ // Current state of the subscription. Allowed values are:
+ // "Installed"
+ // "Preloaded"
+ // "Installing"
+ // See components/adblock/core/subscription/subscription.h for description.
+ DOMString installation_state;
+ // Subscription title (may be empty)
+ DOMString title;
+ // Subscription version (may be empty)
+ DOMString current_version;
+ // Time of last successful installation or update, in ISO 8601 format.
+ // May be passed directly to the Date constructor.
+ DOMString last_installation_time;
+ };
+
+ dictionary SessionStatsEntry {
+ // Subscription url or "adblock:custom" when custom filter was matched
+ DOMString url;
+ // Subscription hits
+ long count;
+ };
+
+ dictionary RequestInfo {
+ // URL of the request element which has been matched.
+ DOMString url;
+ // URLs of the parent frames.
+ DOMString[] parent_frame_urls;
+ // URL of subscription having the filter which matched for the request.
+ DOMString subscription;
+ // Configuration name containing subscription with matched filer.
+ DOMString configuration_name;
+ // A string representation of matched request's resource type.
+ // Possible values are:
+ // - "SCRIPT"
+ // - "IMAGE"
+ // - "STYLESHEET"
+ // - "OBJECT"
+ // - "SUBDOCUMENT"
+ // - "WEBSOCKET"
+ // - "WEBRTC"
+ // - "PING"
+ // - "XMLHTTPREQUEST"
+ // - "MEDIA"
+ // - "FONT"
+ // - "OTHER" (when none of the above matches)
+ // See: components/adblock/core/common/content_type.h
+ DOMString content_type;
+ // Tab id for which the event is fired. Defaults to -1, a numerical value of
+ // api::tabs::TAB_ID_NONE which means tab id cannot be obtained.
+ long tab_id;
+ // Window id for which the event is fired. Defaults to -1 which is a value
+ // of SessionID::InvalidValue() which means window id cannot be obtained.
+ long window_id;
+ };
+
+ callback CompletionCallback = void();
+ callback ListCallback = void(DOMString[] result);
+ callback SessionStatsCallback = void(SessionStatsEntry[] result);
+ callback StateCallback = void(boolean result);
+ callback SubscriptionsCallback = void(Subscription[] result);
+ callback UrlCallback = void(DOMString result);
+
+ // In order to use any configuration it needs to be created first
+ // in the backend, for example by using $(ref:createConfiguration) call.
+ // Names of all existing configurations can be fetched via
+ // (ref:getConfigurations) call.
+ interface Functions {
+ // Creates new filtering configuration. It is a no-op call if configuration
+ // already exists.
+ static void createConfiguration(DOMString config_name);
+ // Removes existing configuration, no-op when configuration does not exist.
+ // Use it only when |configuration| is no longer needed, otherwise prefer
+ // to disable |configuration| using (ref:setEnabled).
+ static void removeConfiguration(DOMString config_name);
+ // Returns a list of existing configurations.
+ [supportsPromises] static void getConfigurations(ListCallback callback);
+ // Allows to turn filtering configuration on or off.
+ [supportsPromises] static void setEnabled(
+ DOMString configuration,
+ boolean enabled,
+ optional CompletionCallback status);
+ // Returns whether filtering configuration is on.
+ [supportsPromises] static void isEnabled(
+ DOMString configuration,
+ StateCallback callback);
+ // Adds a domain requests should not be blocked on.
+ [supportsPromises] static void addAllowedDomain(
+ DOMString configuration,
+ DOMString domain,
+ optional CompletionCallback status);
+ // Removes a domain requests should not be blocked on.
+ [supportsPromises] static void removeAllowedDomain(
+ DOMString configuration,
+ DOMString domain,
+ optional CompletionCallback status);
+ // Returns a list of domains requests are not blocked on.
+ [supportsPromises] static void getAllowedDomains(
+ DOMString configuration,
+ ListCallback callback);
+ // Adds a custom filter.
+ [supportsPromises] static void addCustomFilter(
+ DOMString configuration,
+ DOMString filter,
+ optional CompletionCallback status);
+ // Removes a custom filter.
+ [supportsPromises] static void removeCustomFilter(
+ DOMString configuration,
+ DOMString filter,
+ optional CompletionCallback status);
+ // Returns a list of custom filters a user set.
+ [supportsPromises] static void getCustomFilters(
+ DOMString configuration,
+ ListCallback callback);
+ // Compiles a list of currently installed subscriptions. Filter lists that
+ // are still being installed and don't yet participate in filtering also
+ // appear on this list and can be discerned by their installation_state.
+ [supportsPromises] static void getFilterLists(
+ DOMString configuration,
+ SubscriptionsCallback callback);
+ // Subscribes to a filter list. If subscription was already done and not
+ // removed later by "unsubscribeFromFilterList()" call then this is a no-op
+ // call, otherwise it initiates a download. |url| must point to a https URL.
+ [supportsPromises] static void subscribeToFilterList(
+ DOMString configuration,
+ DOMString url,
+ optional CompletionCallback status);
+ // Removes a subscription to a filter list downloaded from |url| and deletes
+ // corresponding files from disk. Does nothing if the filter list was never
+ // subscribed to.
+ [supportsPromises] static void unsubscribeFromFilterList(
+ DOMString configuration,
+ DOMString url,
+ optional CompletionCallback status);
+ [supportsPromises] static void getSessionAllowedRequestsCount(
+ SessionStatsCallback callback);
+ // Returns number of blocked requests in a current session (runtime).
+ [supportsPromises] static void getSessionBlockedRequestsCount(
+ SessionStatsCallback callback);
+ // Returns Acceptable Ads url which can be passed to
+ // (ref:subscribeToFilterList) or (ref:unsubscribeFromFilterList).
+ [supportsPromises] static void getAcceptableAdsUrl(UrlCallback callback);
+ };
+
+ interface Events {
+ // Fired when an request is explicitly allowed by an exception rule.
+ static void onRequestAllowed(RequestInfo info);
+
+ // Fired when an request is blocked.
+ static void onRequestBlocked(RequestInfo info);
+
+ // Fired when a whole page is allowlisted in every filtering configuration.
+ static void onPageAllowed(RequestInfo info);
+
+ // Fired when a popup is blocked.
+ static void onPopupBlocked(RequestInfo info);
+
+ // Fired when a popup is allowlisted.
+ static void onPopupAllowed(RequestInfo info);
+
+ // Fired when a subscription has been updated.
+ static void onSubscriptionUpdated(DOMString subscription_url);
+
+ // Fired when configuration enable state changed
+ static void onEnabledStateChanged(DOMString config_name);
+
+ // Fired when subscription added or removed.
+ static void onFilterListsChanged(DOMString config_name);
+
+ // Fired when allowed domain list has been updated.
+ static void onAllowedDomainsChanged(DOMString config_name);
+
+ // Fired when custom filter added or removed.
+ static void onCustomFiltersChanged(DOMString config_name);
+ };
+};
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.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/common/extensions/permissions/chrome_api_permissions.h"
@@ -32,6 +36,8 @@ std::unique_ptr<APIPermission> CreateAPIPermission(
// ChromePermissionMessageProvider::GetPermissionMessages as well.
constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
// Register permissions for all extension types.
+ {APIPermissionID::kAdblockPrivate, "adblockPrivate",
+ APIPermissionInfo::kFlagCannotBeOptional},
{APIPermissionID::kBackground, "background",
APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning},
{APIPermissionID::kDeclarativeContent, "declarativeContent"},
@@ -82,6 +88,8 @@ constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
{APIPermissionID::kEnterpriseNetworkingAttributes,
"enterprise.networkingAttributes",
APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning},
+ {APIPermissionID::kEyeoFilteringPrivate, "eyeoFilteringPrivate",
+ APIPermissionInfo::kFlagCannotBeOptional},
{APIPermissionID::kEnterprisePlatformKeys, "enterprise.platformKeys",
APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning},
{APIPermissionID::kFavicon, "favicon"},
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.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 <stddef.h>
#include <memory>
@@ -863,6 +867,10 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermissionID::kWmDesksPrivate);
skip.insert(APIPermissionID::kSystemLog);
+ // Adblock API is also private (in separate block to minimize conflicts).
+ skip.insert(APIPermissionID::kAdblockPrivate);
+ skip.insert(APIPermissionID::kEyeoFilteringPrivate);
+
// Warned as part of host permissions.
skip.insert(APIPermissionID::kDevtools);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3592,6 +3592,12 @@ if (!is_android) {
]
}
+ ### Extension API module start
+ sources += [
+ "../browser/extensions/api/adblock_private/adblock_private_apitest.cc",
+ "../browser/extensions/api/eyeo_filtering_private/eyeo_filtering_private_apitest.cc",
+ ]
+ ### Extension API module end
if (is_chromeos_ash && enable_extensions) {
deps +=
diff --git a/chrome/test/data/extensions/api_test/adblock_private/empty.js b/chrome/test/data/extensions/api_test/adblock_private/empty.js
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/empty.js
@@ -0,0 +1,14 @@
+// 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 <http://www.gnu.org/licenses/>.
diff --git a/chrome/test/data/extensions/api_test/adblock_private/main.html b/chrome/test/data/extensions/api_test/adblock_private/main.html
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/main.html
@@ -0,0 +1,29 @@
+<!--
+* 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 <http://www.gnu.org/licenses/>.
+-->
+<script src="test.js"></script>
+
+<html>
+
+<head>
+ <title>Adblock private API test</title>
+</head>
+
+<body>
+ <h2>chrome.adblockPrivate.* tests</h2>
+</body>
+
+</html>
diff --git a/chrome/test/data/extensions/api_test/adblock_private/manifest.json b/chrome/test/data/extensions/api_test/adblock_private/manifest.json
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/manifest.json
@@ -0,0 +1,32 @@
+// 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 <http://www.gnu.org/licenses/>.
+{
+ "name": "adblockPrivate API test",
+ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyURY+BO7WO3B/dixoRSitosEKb1OOCsS1EF8dRoywUP+iQlHDJw2JL2A7d/E6JpoBQ/CUxX8lcHcsAs7zC31zb2iosBbfd5mCDd24bjLaIF/WNBRno6QYwbM/J7gCxn/aGFvAXdLnPhs2XFiP7iSQEY67NtTlah9EFGalB45UFUssrxFOXTFWT/gJmRIHqfCSUzHdPmFRJ1Sk6UpyZBPxp2MJAISbfTUhWIXa7WG+JxW95OEtNggfhYzX9wbCVSEU18RiMiMLdqNwHf7hYI30KiwrQhWcaB5kCnvJYEa43JggcE9xAaHV+1t2hSMyo5Xbz2YslI5UfDe8112hGVIUQIDAQAB",
+ "version": "0.1",
+ "incognito": "split",
+ "manifest_version": 2,
+ "background": {
+ "scripts": [
+ "empty.js"
+ ]
+ },
+ "description": "Test of chrome.adblockPrivate interface",
+ "permissions": [
+ "adblockPrivate",
+ "eyeoFilteringPrivate",
+ "<all_urls>"
+ ]
+}
diff --git a/chrome/test/data/extensions/api_test/adblock_private/some-popup.html b/chrome/test/data/extensions/api_test/adblock_private/some-popup.html
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/some-popup.html
@@ -0,0 +1,24 @@
+<!--
+* 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 <http://www.gnu.org/licenses/>.
+-->
+<html>
+<head>
+ <title>Popup content</title>
+</head>
+<body>
+ <p>I am a popup</p>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/adblock_private/test.html b/chrome/test/data/extensions/api_test/adblock_private/test.html
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/test.html
@@ -0,0 +1,25 @@
+<!--
+* 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 <http://www.gnu.org/licenses/>.
+-->
+<html>
+<head>
+ <title>Test file</title>
+</head>
+<body>
+ <img src="some_ad.png">
+ <a href="some-popup.html" id="popup_id" target="_blank">popup link</a>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/adblock_private/test.js b/chrome/test/data/extensions/api_test/adblock_private/test.js
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/adblock_private/test.js
@@ -0,0 +1,538 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+'use strict';
+
+const urlParams = new URLSearchParams(window.location.search);
+
+// This class binds 1st argument for chrome.eyeoFilteringPrivate to 'adblock'
+// configuration and redirects methods renamed in chrome.eyeoFilteringPrivate
+// (eg. `onAdAllowed` => `onRequestAllowed`) which allows test code to
+// seamlessly call the same methods on chrome.adblockPrivate and on
+// chrome.eyeoFilteringPrivate.
+class FilteringPrivateBoundWithAdblock {
+ constructor() {
+ this.delegate = chrome.eyeoFilteringPrivate;
+ this.configuration = 'adblock';
+ this.getSessionAllowedAdsCount =
+ this.delegate.getSessionAllowedRequestsCount;
+ this.getSessionBlockedAdsCount =
+ this.delegate.getSessionBlockedRequestsCount;
+ this.onAdAllowed = this.delegate.onRequestAllowed;
+ this.onAdBlocked = this.delegate.onRequestBlocked;
+ this.onSubscriptionUpdated = this.delegate.onSubscriptionUpdated;
+ this.onAllowedDomainsUpdated = this.delegate.onAllowedDomainsUpdated;
+ const methodsToBind = [
+ 'isEnabled', 'setEnabled', 'getAllowedDomains', 'addAllowedDomain',
+ 'removeAllowedDomain', 'getCustomFilters', 'addCustomFilter',
+ 'removeCustomFilter'
+ ];
+ for (const method of methodsToBind) {
+ this[method] = function() {
+ const args = Array.from(arguments);
+ args.unshift(this.configuration);
+ this.delegate[method].apply(this.delegate, args);
+ }
+ }
+ const methodsToBindRenamed = new Map([
+ ['installSubscription', 'subscribeToFilterList'],
+ ['uninstallSubscription', 'unsubscribeFromFilterList'],
+ ['getInstalledSubscriptions', 'getFilterLists'],
+ ]);
+ methodsToBindRenamed.forEach((value, key) => {
+ this[key] =
+ function() {
+ const args = Array.from(arguments);
+ args.unshift(this.configuration);
+ this.delegate[value].apply(this.delegate, args);
+ }
+ });
+ }
+};
+
+// Set API object for tests, defaults to chrome.adblockPrivate
+let apiObject = chrome.adblockPrivate;
+if (urlParams.get('api') === 'eyeoFilteringPrivate') {
+ apiObject = new FilteringPrivateBoundWithAdblock;
+}
+
+function findEnglishEasyList(item) {
+ console.log(item.title + ' ' + item.url + ' ' + item.languages);
+ return item.title.toLowerCase().includes('easylist') &&
+ item.url.toLowerCase().includes('easylist') &&
+ item.languages.includes('en');
+}
+
+function containsSubscription(subscriptions, url) {
+ for (const subscription of subscriptions) {
+ if (subscription.url === url) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function verifySessionStats(sessionStats, expectedSubscription) {
+ let index = -1;
+ for (let i = 0; i < sessionStats.length; i++) {
+ if (sessionStats[i].url === expectedSubscription) {
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) {
+ chrome.test.fail('Failed: Missing entry in sessionStats');
+ return;
+ }
+ if (sessionStats[index].count != 1) {
+ chrome.test.fail(
+ 'Failed: Expected a single subscription hit number, got: ' +
+ sessionStats[index].count);
+ return;
+ }
+}
+
+function verifyEventData(event, expectedSubscription) {
+ if (event.tab_id < 1) {
+ chrome.test.fail('Failed: Wrong tab_id value');
+ }
+ if (event.window_id < 1) {
+ chrome.test.fail('Failed: Wrong window_id value');
+ }
+ if (event.content_type !== 'XMLHTTPREQUEST') {
+ chrome.test.fail('Failed: Wrong content_type value: ' + event.content_type);
+ }
+ if (event.subscription !== expectedSubscription) {
+ chrome.test.fail('Failed: Wrong subscription value: ' + event.subscription);
+ }
+}
+
+function arrayEquals(a, b) {
+ if (a === b)
+ return true;
+ if (a === null || b === null)
+ return false;
+ if (a.length !== b.length)
+ return false;
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] !== b[i])
+ return false;
+ }
+ return true;
+};
+
+const availableTests = [
+ function setEnabled_isEnabled() {
+ apiObject.setEnabled(false);
+ apiObject.isEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.fail('Failed: ad blocking should NOT be enabled');
+ });
+ apiObject.setEnabled(true);
+ apiObject.isEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.succeed();
+ else
+ chrome.test.fail('Failed: ad blocking should be enabled');
+ });
+ },
+ function setAAEnabled_isAAEnabled() {
+ chrome.adblockPrivate.setAcceptableAdsEnabled(false);
+ chrome.adblockPrivate.isAcceptableAdsEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.fail('Failed: AA should NOT be enabled');
+ });
+ chrome.adblockPrivate.setAcceptableAdsEnabled(true);
+ chrome.adblockPrivate.getInstalledSubscriptions(function(selected) {
+ if (!containsSubscription(
+ selected,
+ 'https://easylist-downloads.adblockplus.org/exceptionrules.txt')) {
+ chrome.test.fail('Failed: AA subscription should be on the list');
+ }
+ });
+ chrome.adblockPrivate.isAcceptableAdsEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.succeed();
+ else
+ chrome.test.fail('Failed: AA should be enabled');
+ });
+ },
+ function setAAEnabled_isAAEnabled_newAPI() {
+ const default_config = 'adblock';
+ chrome.eyeoFilteringPrivate.getAcceptableAdsUrl(function(aa_url) {
+ chrome.eyeoFilteringPrivate.unsubscribeFromFilterList(
+ default_config, aa_url);
+ chrome.adblockPrivate.isAcceptableAdsEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.fail('Failed: AA should NOT be enabled');
+ });
+ chrome.eyeoFilteringPrivate.getAcceptableAdsUrl(function(aa_url) {
+ chrome.eyeoFilteringPrivate.subscribeToFilterList(
+ default_config, aa_url);
+ chrome.adblockPrivate.isAcceptableAdsEnabled(function(enabled) {
+ if (enabled)
+ chrome.test.succeed();
+ else
+ chrome.test.fail('Failed: AA should be enabled');
+ });
+ });
+ });
+ },
+ function getBuiltInSubscriptions() {
+ chrome.adblockPrivate.getBuiltInSubscriptions(function(recommended) {
+ const found = recommended.find(findEnglishEasyList);
+ if (found) {
+ chrome.test.succeed();
+ } else {
+ chrome.test.fail('Failed: invalid built-in subscriptions');
+ }
+ });
+ },
+ // This test works because at the beginning getInstalledSubscriptions returns
+ // just default entries from recommended subscriptions.
+ function installedSubscriptionsDataSchema() {
+ const disabled = !!urlParams.get('disabled');
+ if (disabled) {
+ apiObject.setEnabled(false);
+ }
+ apiObject.getInstalledSubscriptions(function(installed) {
+ for (const subscription of installed) {
+ if (!(subscription.installation_state == 'Unknown' && disabled ||
+ subscription.installation_state != 'Unknown' && !disabled))
+ chrome.test.fail(
+ 'Failed: Must contain valid "installation_state" property');
+ if (!subscription.current_version && !disabled)
+ chrome.test.fail('Failed: Must contain "current_version" property');
+ if (!subscription.last_installation_time && !disabled)
+ chrome.test.fail(
+ 'Failed: Must contain "last_installation_time" property');
+ if (!subscription.title && !disabled)
+ chrome.test.fail('Failed: Must contain "title" property');
+ if (!subscription.url)
+ chrome.test.fail('Failed: Must contain "url" property');
+ chrome.test.succeed();
+ }
+ });
+ },
+ function installSubscriptionInvalidURL() {
+ apiObject.installSubscription('http://', function() {
+ if (!chrome.runtime.lastError)
+ chrome.test.fail('Failed: invalid input accepted');
+ else
+ chrome.test.succeed();
+ });
+ },
+ function uninstallSubscriptionInvalidURL() {
+ apiObject.uninstallSubscription('http://', function() {
+ if (!chrome.runtime.lastError)
+ chrome.test.fail('Failed: invalid input accepted');
+ else
+ chrome.test.succeed();
+ });
+ },
+ function subscriptionsManagement() {
+ const kEasylist = urlParams.get('easylist');
+ const kExceptionrules = urlParams.get('exceptions');
+ const kABPFilters = urlParams.get('snippets');
+ const kCustom = 'https://example.com/subscription.txt';
+
+ function containsDefaultSubscriptions(subscriptions) {
+ return containsSubscription(subscriptions, kEasylist) &&
+ containsSubscription(subscriptions, kExceptionrules) &&
+ containsSubscription(subscriptions, kABPFilters);
+ }
+
+ if (urlParams.get('disabled')) {
+ apiObject.setEnabled(false);
+ }
+
+ apiObject.getInstalledSubscriptions(function(installed) {
+ if (installed.length) {
+ if (!containsDefaultSubscriptions(installed)) {
+ chrome.test.fail('Failed: Should contain all default subscriptions');
+ }
+ for (const subscription of installed) {
+ apiObject.uninstallSubscription(subscription.url);
+ }
+ } else {
+ chrome.test.fail('Failed: Should contain default subscriptions');
+ }
+ apiObject.getInstalledSubscriptions(function(installed) {
+ if (installed.length) {
+ chrome.test.fail(
+ 'Failed: There shouldn\'t be any installed subscriptions');
+ }
+ apiObject.installSubscription(kEasylist);
+ apiObject.installSubscription(kExceptionrules);
+ apiObject.installSubscription(kABPFilters);
+ apiObject.getInstalledSubscriptions(function(installed) {
+ if (installed.length) {
+ if (!containsDefaultSubscriptions(installed)) {
+ chrome.test.fail(
+ 'Failed: Should contain all default subscriptions');
+ }
+ } else {
+ chrome.test.fail('Failed: Should contain default subscriptions');
+ }
+ apiObject.installSubscription(kCustom);
+ apiObject.getInstalledSubscriptions(function(installed) {
+ if (!containsSubscription(installed, kCustom)) {
+ chrome.test.fail('Failed: Should contain custom subscription');
+ }
+ apiObject.uninstallSubscription(kCustom);
+ apiObject.getInstalledSubscriptions(function(installed) {
+ if (containsSubscription(installed, kCustom)) {
+ chrome.test.fail(
+ 'Failed: Should not contain custom subscription');
+ } else {
+ chrome.test.succeed();
+ }
+ });
+ });
+ });
+ });
+ });
+ },
+ function allowedDomainsManagement() {
+ apiObject.getAllowedDomains(function(domains) {
+ if (domains.length) {
+ for (const domain of domains)
+ apiObject.removeAllowedDomain(domain);
+ }
+
+ apiObject.getAllowedDomains(function(domains) {
+ if (domains.length) {
+ chrome.test.fail('Failed: There shouldn\'t be any allowed domains');
+ return;
+ }
+
+ apiObject.addAllowedDomain('foo.bar');
+ apiObject.addAllowedDomain('bar.baz');
+ apiObject.getAllowedDomains(function(domains) {
+ if (domains.length != 2) {
+ chrome.test.fail('Failed: There should be 2 allowed domains');
+ return;
+ }
+
+ if (domains.indexOf('foo.bar') == -1 ||
+ domains.indexOf('bar.baz') == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected allowed domains');
+ return;
+ }
+
+ apiObject.removeAllowedDomain('foo.bar');
+ apiObject.removeAllowedDomain('bar.baz');
+
+ apiObject.getAllowedDomains(function(domains) {
+ if (domains.length)
+ chrome.test.fail('Failed: Still have allowed domains');
+ else
+ chrome.test.succeed();
+ });
+ });
+ });
+ });
+ },
+ function customFiltersManagement() {
+ apiObject.getCustomFilters(function(filters) {
+ if (filters.length) {
+ for (const filter of filters)
+ apiObject.removeCustomFilter(filter);
+ }
+
+ apiObject.getCustomFilters(function(filters) {
+ if (filters.length) {
+ chrome.test.fail('Failed: There shouldn\'t be any custom filters');
+ return;
+ }
+
+ apiObject.addCustomFilter('foo.bar');
+ apiObject.addCustomFilter('bar.baz');
+ apiObject.getCustomFilters(function(filters) {
+ if (filters.length != 2) {
+ chrome.test.fail('Failed: There should be 2 custom filters');
+ return;
+ }
+
+ if (filters.indexOf('foo.bar') == -1 ||
+ filters.indexOf('bar.baz') == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected custom filters');
+ return;
+ }
+
+ apiObject.removeCustomFilter('foo.bar');
+ apiObject.removeCustomFilter('bar.baz');
+
+ apiObject.getCustomFilters(function(filters) {
+ if (filters.length)
+ chrome.test.fail('Failed: Still have custom filters');
+ else
+ chrome.test.succeed();
+ });
+ });
+ });
+ });
+ },
+ function adBlockedEvents() {
+ const expectedSubscription = urlParams.get('subscription_url');
+ apiObject.onSubscriptionUpdated.addListener(function(subscription) {
+ if (subscription !== expectedSubscription)
+ chrome.test.fail('Failed: Unexpected subscription: ' + subscription);
+
+ apiObject.onAdBlocked.addListener(function(e) {
+ verifyEventData(e, expectedSubscription);
+ if (e.url.includes('test1.png')) {
+ chrome.test.succeed();
+ }
+ });
+ const request = new XMLHttpRequest();
+ const handler = function() {};
+ request.onload = handler;
+ request.onerror = handler;
+ request.open('GET', 'https://example.com/test1.png', true);
+ request.send();
+ });
+ apiObject.installSubscription(expectedSubscription);
+ },
+ function adAllowedEvents() {
+ const expectedSubscription = urlParams.get('subscription_url');
+ apiObject.onSubscriptionUpdated.addListener(function(subscription) {
+ if (subscription !== expectedSubscription)
+ chrome.test.fail('Failed: Unexpected subscription: ' + subscription);
+
+ apiObject.onAdAllowed.addListener(function(e) {
+ verifyEventData(e, expectedSubscription);
+ if (e.url.includes('test2.png')) {
+ chrome.test.succeed();
+ }
+ });
+ const request = new XMLHttpRequest();
+ const handler = function() {};
+ request.onload = handler;
+ request.onerror = handler;
+ request.open('GET', 'https://example.com/test2.png', true);
+ request.send();
+ });
+ apiObject.installSubscription(expectedSubscription);
+ },
+ function sessionStats() {
+ const expectedSubscription = urlParams.get('subscription_url');
+ // Verify that subscription was downloaded and update event triggered,
+ // then verify correct number of a session blocked and allowed ads count
+ // for this subscription.
+ apiObject.onSubscriptionUpdated.addListener(function(subscription) {
+ if (subscription !== expectedSubscription)
+ chrome.test.fail('Failed: Unexpected subscription: ' + subscription);
+
+ const handler = function() {
+ apiObject.getSessionBlockedAdsCount(function(sessionStats) {
+ verifySessionStats(sessionStats, expectedSubscription);
+ const handler = function() {
+ apiObject.getSessionAllowedAdsCount(function(sessionStats) {
+ verifySessionStats(sessionStats, expectedSubscription);
+ chrome.test.succeed();
+ });
+ };
+ const request = new XMLHttpRequest();
+ request.onload = handler;
+ request.onerror = handler;
+ request.open('GET', 'https://example.com/test4.png', true);
+ request.send();
+ });
+ };
+ const request = new XMLHttpRequest();
+ request.onload = handler;
+ request.onerror = handler;
+ request.open('GET', 'https://example.com/test3.png', true);
+ request.send();
+ });
+ apiObject.installSubscription(expectedSubscription);
+ },
+ function allowedDomainsEvent() {
+ const domain = 'domain.com';
+ let data = [domain];
+ let attempts = 2;
+ chrome.adblockPrivate.onAllowedDomainsChanged.addListener(function() {
+ chrome.adblockPrivate.getAllowedDomains(function(domains) {
+ if (!arrayEquals(data, domains)) {
+ chrome.test.fail('Unexpected domain list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.adblockPrivate.addAllowedDomain(domain);
+ data = [];
+ chrome.adblockPrivate.removeAllowedDomain(domain);
+ },
+ function enabledStateEvent() {
+ let state = false;
+ let attempts = 2;
+ chrome.adblockPrivate.onEnabledStateChanged.addListener(function() {
+ chrome.adblockPrivate.isEnabled(function(enabled) {
+ if (enabled !== state) {
+ chrome.test.fail('Unexpected enabled state');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.adblockPrivate.setEnabled(false);
+ state = true;
+ chrome.adblockPrivate.setEnabled(true);
+ },
+ function filterListsEvent() {
+ const kCustom = 'https://example.com/subscription.txt';
+ let data = [kCustom];
+ let attempts = 2;
+ chrome.adblockPrivate.onFilterListsChanged.addListener(function() {
+ chrome.adblockPrivate.getInstalledSubscriptions(function(custom) {
+ if (!(data.length + 3, custom.length)) {
+ chrome.test.fail('Unexpected subscription list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ data = [];
+ chrome.adblockPrivate.uninstallSubscription(kCustom);
+ });
+ });
+ chrome.adblockPrivate.installSubscription(kCustom);
+ },
+ function customFiltersEvent() {
+ const filter = 'foo.bar';
+ let data = [filter];
+ let attempts = 2;
+ chrome.adblockPrivate.onCustomFiltersChanged.addListener(function() {
+ chrome.adblockPrivate.getCustomFilters(function(filters) {
+ if (!arrayEquals(data, filters)) {
+ chrome.test.fail('Unexpected custom filter list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.adblockPrivate.addCustomFilter(filter);
+ data = [];
+ chrome.adblockPrivate.removeCustomFilter(filter);
+ },
+];
+
+chrome.test.runTests(availableTests.filter(function(op) {
+ return op.name == urlParams.get('subtest');
+}));
diff --git a/chrome/test/data/extensions/api_test/eyeo_filtering_private/empty.js b/chrome/test/data/extensions/api_test/eyeo_filtering_private/empty.js
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/eyeo_filtering_private/empty.js
@@ -0,0 +1,14 @@
+// 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 <http://www.gnu.org/licenses/>.
diff --git a/chrome/test/data/extensions/api_test/eyeo_filtering_private/main.html b/chrome/test/data/extensions/api_test/eyeo_filtering_private/main.html
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/eyeo_filtering_private/main.html
@@ -0,0 +1,29 @@
+<!--
+* 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 <http://www.gnu.org/licenses/>.
+-->
+<script src="test.js"></script>
+
+<html>
+
+<head>
+ <title>Eyeo filtering private API test</title>
+</head>
+
+<body>
+ <h2>chrome.eyeoFilteringPrivate.* tests</h2>
+</body>
+
+</html>
diff --git a/chrome/test/data/extensions/api_test/eyeo_filtering_private/manifest.json b/chrome/test/data/extensions/api_test/eyeo_filtering_private/manifest.json
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/eyeo_filtering_private/manifest.json
@@ -0,0 +1,31 @@
+// 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 <http://www.gnu.org/licenses/>.
+{
+ "name": "eyeoFilteringPrivate API test",
+ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkRxyv6tzqVnC+2gR3QxaN32fynw6GBZd9CXH8huHopx5xZ0fE1gScXnnjna7YW2sc6dhZZv326lRwmsJRwJN+RZpxBQbTD4CuCiqfUo+Xdyigh91QqyScLLRmg3SPsBBF9X/M50LO/6MD2eETiWbQQRy1TXNz52lt6NtjXKmS2lVZzR/jnGyAA96vMOmxeNIJmSYHFOHlSIphAJr/Erd0v1ZcBjJnZxqSrKZwUTHHc/FxcN1YqJkU/6O6gjMLNo3Uv33bqRAYmGUq+TTftwLg2hzEE1OllThcF9VVmQ3HZ5eTqqw/XP/tiQ/vUBflKer2mSVk708VBNpktao44kAtQIDAQAB",
+ "version": "0.1",
+ "incognito": "split",
+ "manifest_version": 3,
+ "background": {
+ "service_worker": "empty.js"
+ },
+ "description": "Test of chrome.eyeoFilteringPrivate interface",
+ "host_permissions": [
+ "<all_urls>"
+ ],
+ "permissions": [
+ "eyeoFilteringPrivate"
+ ]
+}
diff --git a/chrome/test/data/extensions/api_test/eyeo_filtering_private/test.js b/chrome/test/data/extensions/api_test/eyeo_filtering_private/test.js
new file mode 100644
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/eyeo_filtering_private/test.js
@@ -0,0 +1,460 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+'use strict';
+
+const custom_config = 'custom';
+
+async function pollUntil(predicate, pollEveryMs) {
+ return new Promise(r => {
+ const id = setInterval(() => {
+ let ret;
+ if (ret = predicate()) {
+ clearInterval(id);
+ r(ret);
+ }
+ }, pollEveryMs);
+ });
+}
+
+function containsSubscription(subscriptions, url) {
+ for (const subscription of subscriptions) {
+ if (subscription.url === url) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function arrayEquals(a, b) {
+ if (a === b)
+ return true;
+ if (a === null || b === null)
+ return false;
+ if (a.length !== b.length)
+ return false;
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] !== b[i])
+ return false;
+ }
+ return true;
+};
+
+const availableTests = [
+ function createRemoveAndGetConfigurations() {
+ chrome.eyeoFilteringPrivate.getConfigurations(function(configs) {
+ if (configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should NOT be a custom configuration');
+ }
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.getConfigurations(function(configs) {
+ if (!configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should be a custom configuration');
+ }
+ chrome.eyeoFilteringPrivate.removeConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.getConfigurations(function(configs) {
+ if (configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should NOT be a custom configuration');
+ }
+ chrome.test.succeed();
+ });
+ });
+ });
+ },
+ function createRemoveAndGetConfigurationsWithPromises() {
+ chrome.eyeoFilteringPrivate.getConfigurations().then(configs => {
+ if (configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should NOT be a custom configuration');
+ }
+ });
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.getConfigurations().then(configs => {
+ if (!configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should be a custom configuration');
+ }
+ chrome.eyeoFilteringPrivate.removeConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.getConfigurations().then(configs => {
+ if (configs.includes(custom_config)) {
+ chrome.test.fail('Failed: There should NOT be a custom configuration');
+ }
+ chrome.test.succeed();
+ });
+ });
+ },
+ function enableAndDisableConfiguration() {
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config, function(enabled) {
+ if (!enabled) {
+ chrome.test.fail('Failed: Configuration should be enabled');
+ }
+ });
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, false);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config, function(enabled) {
+ if (enabled) {
+ chrome.test.fail('Failed: Configuration should NOT be enabled');
+ }
+ });
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, true);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config, function(enabled) {
+ if (!enabled) {
+ chrome.test.fail('Failed: Configuration should be enabled');
+ }
+ chrome.test.succeed();
+ });
+ },
+ function enableAndDisableConfigurationWithPromises() {
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config).then(enabled => {
+ if (!enabled) {
+ chrome.test.fail('Failed: Configuration should be enabled');
+ }
+ });
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, false);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config)
+ .then(enabled => {
+ if (enabled) {
+ chrome.test.fail('Failed: Configuration should NOT be enabled');
+ }
+ })
+ .catch(error => chrome.test.fail(error));
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, true);
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config).then(enabled => {
+ if (!enabled) {
+ chrome.test.fail('Failed: Configuration should be enabled');
+ }
+ chrome.test.succeed();
+ });
+ },
+ function addAllowedDomainToCustomConfiguration() {
+ const domain = 'domain.com';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.addAllowedDomain(custom_config, domain);
+ chrome.eyeoFilteringPrivate.getAllowedDomains(
+ custom_config, function(domains) {
+ if (domains.length != 1) {
+ chrome.test.fail('Failed: There should be a custom domain');
+ }
+ if (domains.indexOf(domain) == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected custom domain');
+ }
+ });
+ chrome.eyeoFilteringPrivate.removeAllowedDomain(custom_config, domain);
+ chrome.eyeoFilteringPrivate.getAllowedDomains(
+ custom_config, function(domains) {
+ if (domains.length) {
+ chrome.test.fail('Failed: Still have custom domain(s)');
+ }
+ chrome.test.succeed();
+ });
+ },
+ async function addAllowedDomainToCustomConfigurationWithPromises() {
+ const domain = 'domain.com';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ await chrome.eyeoFilteringPrivate.addAllowedDomain(custom_config, domain);
+ chrome.eyeoFilteringPrivate.getAllowedDomains(custom_config)
+ .then(domains => {
+ if (domains.length != 1) {
+ chrome.test.fail('Failed: There should be a custom domain');
+ }
+ if (domains.indexOf(domain) == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected custom domain');
+ }
+ });
+ await chrome.eyeoFilteringPrivate.removeAllowedDomain(
+ custom_config, domain);
+ chrome.eyeoFilteringPrivate.getAllowedDomains(custom_config)
+ .then(domains => {
+ if (domains.length) {
+ chrome.test.fail('Failed: Still have custom domain(s)');
+ }
+ chrome.test.succeed();
+ });
+ },
+ function addCustomFilterToCustomConfiguration() {
+ const filter = '||foo.bar';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.addCustomFilter(custom_config, filter);
+ chrome.eyeoFilteringPrivate.getCustomFilters(
+ custom_config, function(filters) {
+ if (filters.length != 1) {
+ chrome.test.fail('Failed: There should be a custom filter');
+ }
+ if (filters.indexOf(filter) == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected custom filter');
+ }
+ });
+ chrome.eyeoFilteringPrivate.removeCustomFilter(custom_config, filter);
+ chrome.eyeoFilteringPrivate.getCustomFilters(
+ custom_config, function(filters) {
+ if (filters.length) {
+ chrome.test.fail('Failed: Still have custom filter(s)');
+ }
+ chrome.test.succeed();
+ });
+ },
+ async function addCustomFilterToCustomConfigurationWithPromises() {
+ const filter = '||foo.bar';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ await chrome.eyeoFilteringPrivate.addCustomFilter(custom_config, filter);
+ chrome.eyeoFilteringPrivate.getCustomFilters(custom_config)
+ .then(filters => {
+ if (filters.length != 1) {
+ chrome.test.fail('Failed: There should be a custom filter');
+ }
+ if (filters.indexOf(domain) == -1) {
+ chrome.test.fail('Failed: Didn\'t find expected custom filter');
+ }
+ });
+ await chrome.eyeoFilteringPrivate.removeCustomFilter(custom_config, filter);
+ chrome.eyeoFilteringPrivate.getCustomFilters(custom_config)
+ .then(filters => {
+ if (filters.length) {
+ chrome.test.fail('Failed: Still have custom filter(s)');
+ }
+ chrome.test.succeed();
+ });
+ },
+ function subscribeToFilterListInCustomConfiguration() {
+ const subscription = 'https://example.com/subscription.txt';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.subscribeToFilterList(
+ custom_config, subscription, function() {
+ chrome.eyeoFilteringPrivate.getFilterLists(
+ custom_config, function(subscriptions) {
+ if (subscriptions.length != 1) {
+ chrome.test.fail(
+ 'Failed: There should be a custom subscription');
+ return;
+ }
+ if (!containsSubscription(subscriptions, subscription)) {
+ chrome.test.fail(
+ 'Failed: Didn\'t find expected custom subscription');
+ return;
+ }
+ chrome.eyeoFilteringPrivate.unsubscribeFromFilterList(
+ custom_config, subscription, function() {
+ chrome.eyeoFilteringPrivate.getFilterLists(
+ custom_config, function(subscriptions) {
+ if (subscriptions.length) {
+ chrome.test.fail(
+ 'Failed: Still have custom subscription(s)');
+ }
+ chrome.test.succeed();
+ });
+ });
+ });
+ });
+ },
+ async function subscribeToFilterListInCustomConfigurationWithPromises() {
+ const subscription = 'https://example.com/subscription.txt';
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ await chrome.eyeoFilteringPrivate.subscribeToFilterList(
+ custom_config, subscription);
+ chrome.eyeoFilteringPrivate.getFilterLists(custom_config)
+ .then(subscriptions => {
+ if (subscriptions.length != 1) {
+ chrome.test.fail('Failed: There should be a custom subscription');
+ return;
+ }
+ if (!containsSubscription(subscriptions, subscription)) {
+ chrome.test.fail(
+ 'Failed: Didn\'t find expected custom subscription');
+ return;
+ }
+ });
+ await chrome.eyeoFilteringPrivate.unsubscribeFromFilterList(
+ custom_config, subscription);
+ chrome.eyeoFilteringPrivate.getFilterLists(custom_config)
+ .then(subscriptions => {
+ if (subscriptions.length) {
+ chrome.test.fail('Failed: Still have custom subscription(s)');
+ }
+ chrome.test.succeed();
+ });
+ },
+ async function missingConfiguration() {
+ const input = 'https://dummy.com';
+ const expectedError = 'Configuration with name \'custom\' does not exist!';
+ const setters = [
+ 'subscribeToFilterList', 'unsubscribeFromFilterList', 'addAllowedDomain',
+ 'removeAllowedDomain', 'addCustomFilter', 'removeCustomFilter'
+ ];
+ const getters = [
+ 'isEnabled', 'getFilterLists', 'getAllowedDomains', 'getCustomFilters'
+ ];
+ const allMethodsCount = 1 + setters.length + getters.length;
+ let counter = 0;
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, false, function() {
+ if (!chrome.runtime.lastError) {
+ chrome.test.fail('Failed: missing configuration accepted');
+ }
+ chrome.test.assertEq(expectedError, chrome.runtime.lastError.message);
+ ++counter;
+ });
+ for (const method of setters) {
+ chrome.eyeoFilteringPrivate[method](custom_config, input, function() {
+ if (!chrome.runtime.lastError) {
+ chrome.test.fail('Failed: missing configuration accepted');
+ }
+ chrome.test.assertEq(expectedError, chrome.runtime.lastError.message);
+ ++counter;
+ });
+ }
+ for (const method of getters) {
+ chrome.eyeoFilteringPrivate[method](custom_config, function(result) {
+ if (!chrome.runtime.lastError) {
+ chrome.test.fail('Failed: missing configuration accepted');
+ }
+ chrome.test.assertEq(expectedError, chrome.runtime.lastError.message);
+ ++counter;
+ });
+ }
+ await pollUntil(() => counter === allMethodsCount, 100);
+ chrome.test.succeed();
+ },
+ async function missingConfigurationWithPromises() {
+ const input = 'https://dummy.com';
+ const expectedError =
+ 'Error: Configuration with name \'custom\' does not exist!'
+ const setters = [
+ 'subscribeToFilterList', 'unsubscribeFromFilterList', 'addAllowedDomain',
+ 'removeAllowedDomain', 'addCustomFilter', 'removeCustomFilter'
+ ];
+ const getters = [
+ 'isEnabled', 'getFilterLists', 'getAllowedDomains', 'getCustomFilters'
+ ];
+ const allMethodsCount = 1 + setters.length + getters.length;
+ let counter = 0;
+ const errorHandler = function(error) {
+ chrome.test.assertEq(expectedError, error.toString());
+ ++counter;
+ };
+ await chrome.eyeoFilteringPrivate.setEnabled(custom_config, false)
+ .catch(error => errorHandler(error));
+ for (const method of setters) {
+ await chrome.eyeoFilteringPrivate[method](custom_config, input)
+ .catch(error => errorHandler(error));
+ }
+ for (const method of getters) {
+ await chrome.eyeoFilteringPrivate[method](custom_config)
+ .catch(error => errorHandler(error));
+ }
+ if (counter == allMethodsCount) {
+ chrome.test.succeed();
+ } else {
+ chrome.test.fail('Failed: expected missing configuration for every call');
+ }
+ },
+ function allowedDomainsEvent() {
+ const domain = 'domain.com';
+ let data = [domain];
+ let attempts = 2;
+ chrome.eyeoFilteringPrivate.onAllowedDomainsChanged.addListener(function(
+ config_name) {
+ if (config_name != custom_config) {
+ chrome.test.fail('Failed: Wrong config name');
+ }
+ chrome.eyeoFilteringPrivate.getAllowedDomains(
+ custom_config, function(domains) {
+ if (!arrayEquals(data, domains)) {
+ chrome.test.fail('Unexpected domain list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.addAllowedDomain(custom_config, domain);
+ data = [];
+ chrome.eyeoFilteringPrivate.removeAllowedDomain(custom_config, domain);
+ },
+ function enabledStateEvent() {
+ let state = false;
+ let attempts = 2;
+ chrome.eyeoFilteringPrivate.onEnabledStateChanged.addListener(function(
+ config_name) {
+ if (config_name != custom_config) {
+ chrome.test.fail('Failed: Wrong config name');
+ }
+ chrome.eyeoFilteringPrivate.isEnabled(custom_config, function(enabled) {
+ if (enabled !== state) {
+ chrome.test.fail('Unexpected enabled state');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, false);
+ state = true;
+ chrome.eyeoFilteringPrivate.setEnabled(custom_config, true);
+ },
+ function filterListsEvent() {
+ const domain = 'http://domain.com/';
+ let data = [domain];
+ let attempts = 2;
+ chrome.eyeoFilteringPrivate.onFilterListsChanged.addListener(function(
+ config_name) {
+ if (config_name != custom_config) {
+ chrome.test.fail('Failed: Wrong config name');
+ }
+ chrome.eyeoFilteringPrivate.getFilterLists(
+ custom_config, function(custom) {
+ if (!arrayEquals(data, custom)) {
+ chrome.test.fail('Unexpected subscription list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.subscribeToFilterList(custom_config, domain);
+ data = [];
+ chrome.eyeoFilteringPrivate.unsubscribeFromFilterList(
+ custom_config, domain);
+ },
+ function customFiltersEvent() {
+ const filter = 'foo.bar';
+ let data = [filter];
+ let attempts = 2;
+ chrome.eyeoFilteringPrivate.onCustomFiltersChanged.addListener(function(
+ config_name) {
+ if (config_name != custom_config) {
+ chrome.test.fail('Failed: Wrong config name');
+ }
+ chrome.eyeoFilteringPrivate.getCustomFilters(
+ custom_config, function(filters) {
+ if (!arrayEquals(data, filters)) {
+ chrome.test.fail('Unexpected custom filter list');
+ }
+ if (--attempts == 0) {
+ chrome.test.succeed();
+ }
+ });
+ });
+ chrome.eyeoFilteringPrivate.createConfiguration(custom_config);
+ chrome.eyeoFilteringPrivate.addCustomFilter(custom_config, filter);
+ data = [];
+ chrome.eyeoFilteringPrivate.removeCustomFilter(custom_config, filter);
+ },
+];
+
+const urlParams = new URLSearchParams(window.location.search);
+chrome.test.runTests(availableTests.filter(function(op) {
+ return op.name == urlParams.get('subtest');
+}));
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h
--- a/extensions/browser/extension_event_histogram_value.h
+++ b/extensions/browser/extension_event_histogram_value.h
@@ -1,6 +1,10 @@
// 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.
#ifndef EXTENSIONS_BROWSER_EXTENSION_EVENT_HISTOGRAM_VALUE_H_
#define EXTENSIONS_BROWSER_EXTENSION_EVENT_HISTOGRAM_VALUE_H_
@@ -40,7 +44,8 @@ enum HistogramValue {
APP_WINDOW_ON_MAXIMIZED = 19,
APP_WINDOW_ON_MINIMIZED = 20,
APP_WINDOW_ON_RESTORED = 21,
- DELETED_AUDIO_MODEM_ON_RECEIVED = 22,
+ EYEO_EVENT = 22, // Reusing a DELETED_AUDIO_MODEM_ON_RECEIVED to avoid merge
+ // conflicts.
DELETED_AUDIO_MODEM_ON_TRANSMIT_FAIL = 23,
DELETED_AUDIO_ON_DEVICE_CHANGED = 24,
AUDIO_ON_DEVICES_CHANGED = 25,
diff --git a/extensions/common/mojom/api_permission_id.mojom b/extensions/common/mojom/api_permission_id.mojom
--- a/extensions/common/mojom/api_permission_id.mojom
+++ b/extensions/common/mojom/api_permission_id.mojom
@@ -1,6 +1,10 @@
// Copyright 2021 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.
module extensions.mojom;
@@ -279,6 +283,8 @@ enum APIPermissionID {
kAccessibilityServicePrivate = 252,
kUserScripts = 253,
kChromeOSBluetoothPeripheralsInfo = 254,
+ kAdblockPrivate = 999,
+ kEyeoFilteringPrivate = 1000,
// Add new entries at the end of the enum and be sure to update the
// "ExtensionPermission3" enum in tools/metrics/histograms/enums.xml
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -17,6 +17,9 @@ https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histogra
Please pretty-print and validate your edits by running the pretty_print.py
and validate_format.py scripts in the same directory as this file before
uploading your change for review. These are checked by presubmit scripts.
+
+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.
-->
<histogram-configuration>
@@ -35304,7 +35307,7 @@ Called by update_extension_histograms.py.-->
<int value="19" label="APP_WINDOW_ON_MAXIMIZED"/>
<int value="20" label="APP_WINDOW_ON_MINIMIZED"/>
<int value="21" label="APP_WINDOW_ON_RESTORED"/>
- <int value="22" label="DELETED_AUDIO_MODEM_ON_RECEIVED"/>
+ <int value="22" label="EYEO_EVENT"/>
<int value="23" label="DELETED_AUDIO_MODEM_ON_TRANSMIT_FAIL"/>
<int value="24" label="DELETED_AUDIO_ON_DEVICE_CHANGED"/>
<int value="25" label="AUDIO_ON_DEVICES_CHANGED"/>
@@ -38452,6 +38455,8 @@ Called by update_extension_permission.py.-->
<int value="252" label="kAccessibilityServicePrivate"/>
<int value="253" label="kUserScripts"/>
<int value="254" label="kChromeOSBluetoothPeripheralsInfo"/>
+ <int value="999" label="kAdblockPrivate"/>
+ <int value="1000" label="kEyeoFilteringPrivate"/>
</enum>
<enum name="ExtensionPointEnableState">
diff --git a/tools/typescript/definitions/adblock_private.d.ts b/tools/typescript/definitions/adblock_private.d.ts
new file mode 100644
--- /dev/null
+++ b/tools/typescript/definitions/adblock_private.d.ts
@@ -0,0 +1,172 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+/** @fileoverview Type definitions for chrome.adblockPrivate API. */
+
+import {ChromeEvent} from './chrome_event.js';
+
+declare global {
+ export namespace chrome {
+ export namespace adblockPrivate {
+
+ export interface BuiltInSubscription {
+ url: string;
+ title: string;
+ languages: string[];
+ }
+
+ export interface Subscription {
+ url: string;
+ installation_state: string;
+ title: string;
+ current_version: string;
+ last_installation_time: string;
+ }
+
+ export interface SessionStatsEntry {
+ url: string;
+ count: number;
+ }
+
+ export interface AdInfo {
+ url: string;
+ parent_frame_urls: string[];
+ subscription: string;
+ configuration_name: string;
+ content_type: string;
+ tab_id: number;
+ window_id: number;
+ }
+
+ export const onAdAllowed: ChromeEvent<(
+ info: AdInfo,
+ ) => void>;
+
+ export const onAdBlocked: ChromeEvent<(
+ info: AdInfo,
+ ) => void>;
+
+ export const onPageAllowed: ChromeEvent<(
+ info: AdInfo,
+ ) => void>;
+
+ export const onPopupBlocked: ChromeEvent<(
+ info: AdInfo,
+ ) => void>;
+
+ export const onPopupAllowed: ChromeEvent<(
+ info: AdInfo,
+ ) => void>;
+
+ export const onSubscriptionUpdated: ChromeEvent<(
+ subscription_url: string,
+ ) => void>;
+
+ export const onEnabledStateChanged: ChromeEvent<(
+ ) => void>;
+
+ export const onFilterListsChanged: ChromeEvent<(
+ ) => void>;
+
+ export const onAllowedDomainsChanged: ChromeEvent<(
+ ) => void>;
+
+ export const onCustomFiltersChanged: ChromeEvent<(
+ ) => void>;
+
+ export function setEnabled(
+ enabled: boolean,
+ ): void;
+
+ export function isEnabled(
+ callback: (
+ result: boolean,
+ ) => void,
+ ): void;
+
+ export function setAcceptableAdsEnabled(
+ enabled: boolean,
+ ): void;
+
+ export function isAcceptableAdsEnabled(
+ callback: (
+ result: boolean,
+ ) => void,
+ ): void;
+
+ export function getBuiltInSubscriptions(
+ callback: (
+ result: BuiltInSubscription[],
+ ) => void,
+ ): void;
+
+ export function addAllowedDomain(
+ domain: string,
+ ): void;
+
+ export function removeAllowedDomain(
+ domain: string,
+ ): void;
+
+ export function getAllowedDomains(
+ callback: (
+ result: string[],
+ ) => void,
+ ): void;
+
+ export function addCustomFilter(
+ filter: string,
+ ): void;
+
+ export function removeCustomFilter(
+ filter: string,
+ ): void;
+
+ export function getCustomFilters(
+ callback: (
+ result: string[],
+ ) => void,
+ ): void;
+
+ export function getSessionAllowedAdsCount(
+ callback: (
+ result: SessionStatsEntry[],
+ ) => void,
+ ): void;
+
+ export function getSessionBlockedAdsCount(
+ callback: (
+ result: SessionStatsEntry[],
+ ) => void,
+ ): void;
+
+ export function getInstalledSubscriptions(
+ callback: (
+ result: Subscription[],
+ ) => void,
+ ): void;
+
+ export function installSubscription(
+ url: string,
+ feedback?: () => void,
+ ): void;
+
+ export function uninstallSubscription(
+ url: string,
+ feedback?: () => void,
+ ): void;
+ }
+ }
+}
diff --git a/tools/typescript/definitions/eyeo_filtering_private.d.ts b/tools/typescript/definitions/eyeo_filtering_private.d.ts
new file mode 100644
--- /dev/null
+++ b/tools/typescript/definitions/eyeo_filtering_private.d.ts
@@ -0,0 +1,249 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+/** @fileoverview Type definitions for chrome.eyeoFilteringPrivate API. */
+
+import {ChromeEvent} from './chrome_event.js';
+
+declare global {
+ export namespace chrome {
+ export namespace eyeoFilteringPrivate {
+
+ export interface Subscription {
+ url: string;
+ installation_state: string;
+ title: string;
+ current_version: string;
+ last_installation_time: string;
+ }
+
+ export interface SessionStatsEntry {
+ url: string;
+ count: number;
+ }
+
+ export interface RequestInfo {
+ url: string;
+ parent_frame_urls: string[];
+ subscription: string;
+ configuration_name: string;
+ content_type: string;
+ tab_id: number;
+ window_id: number;
+ }
+
+ export const onRequestAllowed: ChromeEvent<(
+ info: RequestInfo,
+ ) => void>;
+
+ export const onRequestBlocked: ChromeEvent<(
+ info: RequestInfo,
+ ) => void>;
+
+ export const onPageAllowed: ChromeEvent<(
+ info: RequestInfo,
+ ) => void>;
+
+ export const onPopupBlocked: ChromeEvent<(
+ info: RequestInfo,
+ ) => void>;
+
+ export const onPopupAllowed: ChromeEvent<(
+ info: RequestInfo,
+ ) => void>;
+
+ export const onSubscriptionUpdated: ChromeEvent<(
+ subscription_url: string,
+ ) => void>;
+
+ export const onEnabledStateChanged: ChromeEvent<(
+ config_name: string,
+ ) => void>;
+
+ export const onFilterListsChanged: ChromeEvent<(
+ config_name: string,
+ ) => void>;
+
+ export const onAllowedDomainsChanged: ChromeEvent<(
+ config_name: string,
+ ) => void>;
+
+ export const onCustomFiltersChanged: ChromeEvent<(
+ config_name: string,
+ ) => void>;
+
+ export function createConfiguration(
+ config_name: string,
+ ): void;
+
+ export function removeConfiguration(
+ config_name: string,
+ ): void;
+
+ export function getConfigurations(): Promise<string[]>;
+
+ export function getConfigurations(
+ callback?: (
+ result: string[],
+ ) => void,
+ ): void;
+
+ export function setEnabled(
+ configuration: string,
+ enabled: boolean,
+ ): Promise<void>;
+
+ export function setEnabled(
+ configuration: string,
+ enabled: boolean,
+ status?: () => void,
+ ): void;
+
+ export function isEnabled(
+ configuration: string,
+ ): Promise<boolean>;
+
+ export function isEnabled(
+ configuration: string,
+ callback?: (
+ result: boolean,
+ ) => void,
+ ): void;
+
+ export function addAllowedDomain(
+ configuration: string,
+ domain: string,
+ ): Promise<void>;
+
+ export function addAllowedDomain(
+ configuration: string,
+ domain: string,
+ status?: () => void,
+ ): void;
+
+ export function removeAllowedDomain(
+ configuration: string,
+ domain: string,
+ ): Promise<void>;
+
+ export function removeAllowedDomain(
+ configuration: string,
+ domain: string,
+ status?: () => void,
+ ): void;
+
+ export function getAllowedDomains(
+ configuration: string,
+ ): Promise<string[]>;
+
+ export function getAllowedDomains(
+ configuration: string,
+ callback?: (
+ result: string[],
+ ) => void,
+ ): void;
+
+ export function addCustomFilter(
+ configuration: string,
+ filter: string,
+ ): Promise<void>;
+
+ export function addCustomFilter(
+ configuration: string,
+ filter: string,
+ status?: () => void,
+ ): void;
+
+ export function removeCustomFilter(
+ configuration: string,
+ filter: string,
+ ): Promise<void>;
+
+ export function removeCustomFilter(
+ configuration: string,
+ filter: string,
+ status?: () => void,
+ ): void;
+
+ export function getCustomFilters(
+ configuration: string,
+ ): Promise<string[]>;
+
+ export function getCustomFilters(
+ configuration: string,
+ callback?: (
+ result: string[],
+ ) => void,
+ ): void;
+
+ export function getFilterLists(
+ configuration: string,
+ ): Promise<Subscription[]>;
+
+ export function getFilterLists(
+ configuration: string,
+ callback?: (
+ result: Subscription[],
+ ) => void,
+ ): void;
+
+ export function subscribeToFilterList(
+ configuration: string,
+ url: string,
+ ): Promise<void>;
+
+ export function subscribeToFilterList(
+ configuration: string,
+ url: string,
+ status?: () => void,
+ ): void;
+
+ export function unsubscribeFromFilterList(
+ configuration: string,
+ url: string,
+ ): Promise<void>;
+
+ export function unsubscribeFromFilterList(
+ configuration: string,
+ url: string,
+ status?: () => void,
+ ): void;
+
+ export function getSessionAllowedRequestsCount(): Promise<SessionStatsEntry[]>;
+
+ export function getSessionAllowedRequestsCount(
+ callback?: (
+ result: SessionStatsEntry[],
+ ) => void,
+ ): void;
+
+ export function getSessionBlockedRequestsCount(): Promise<SessionStatsEntry[]>;
+
+ export function getSessionBlockedRequestsCount(
+ callback?: (
+ result: SessionStatsEntry[],
+ ) => void,
+ ): void;
+
+ export function getAcceptableAdsUrl(): Promise<string>;
+
+ export function getAcceptableAdsUrl(
+ callback?: (
+ result: string,
+ ) => void,
+ ): void;
+ }
+ }
+}
--
2.25.1