2229 lines
88 KiB
Diff
2229 lines
88 KiB
Diff
From: chromium-sdk <project_26591639_bot@noreply.gitlab.com>
|
|
Date: Fri, 14 Feb 2025 08:26:39 +0100
|
|
Subject: eyeo Browser Ad filtering Solution: Android API Module
|
|
|
|
Based on Chromium 133.0.6943.49
|
|
|
|
Pre-requisites: eyeo Browser Ad filtering Solution: Base Module
|
|
---
|
|
chrome/android/BUILD.gn | 12 +
|
|
chrome/android/chrome_java_sources.gni | 4 +
|
|
.../browser/adblock/TabIdTranslator.java | 36 ++
|
|
chrome/browser/BUILD.gn | 4 +
|
|
.../android/adblock/tab_id_translator_jni.cc | 43 ++
|
|
components/adblock/android/BUILD.gn | 107 +++++
|
|
.../adblock/android/adblock_controller_jni.cc | 133 ++++++
|
|
.../filtering_configuration_android.cc | 246 ++++++++++
|
|
.../android/filtering_configuration_android.h | 94 ++++
|
|
.../components/adblock/AdblockController.java | 283 ++++++++++++
|
|
.../components/adblock/AdblockSwitches.java | 22 +
|
|
.../components/adblock/ContentType.java | 61 +++
|
|
.../adblock/FilteringConfiguration.java | 424 ++++++++++++++++++
|
|
.../ResourceClassificationNotifier.java | 233 ++++++++++
|
|
.../adblock/ResourceFilteringCounters.java | 111 +++++
|
|
...esource_classification_notifier_android.cc | 166 +++++++
|
|
...resource_classification_notifier_android.h | 72 +++
|
|
17 files changed, 2051 insertions(+)
|
|
create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java
|
|
create mode 100644 chrome/browser/android/adblock/tab_id_translator_jni.cc
|
|
create mode 100644 components/adblock/android/BUILD.gn
|
|
create mode 100644 components/adblock/android/adblock_controller_jni.cc
|
|
create mode 100644 components/adblock/android/filtering_configuration_android.cc
|
|
create mode 100644 components/adblock/android/filtering_configuration_android.h
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockController.java
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/AdblockSwitches.java
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/ContentType.java
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/FilteringConfiguration.java
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java
|
|
create mode 100644 components/adblock/android/java/src/org/chromium/components/adblock/ResourceFilteringCounters.java
|
|
create mode 100644 components/adblock/android/resource_classification_notifier_android.cc
|
|
create mode 100644 components/adblock/android/resource_classification_notifier_android.h
|
|
|
|
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
|
|
--- a/chrome/android/BUILD.gn
|
|
+++ b/chrome/android/BUILD.gn
|
|
@@ -1,6 +1,9 @@
|
|
# Copyright 2014 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
+#
|
|
+# This source code is a part of eyeo Chromium SDK.
|
|
+# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file.
|
|
|
|
import("//build/config/android/config.gni")
|
|
import("//build/config/cronet/config.gni")
|
|
@@ -574,6 +577,7 @@ if (_is_default_toolchain) {
|
|
"//chrome/browser/xsurface:java",
|
|
"//chrome/browser/xsurface_provider:dependency_provider_impl_java",
|
|
"//chrome/browser/xsurface_provider:java",
|
|
+ "//components/adblock/android:adblock_controller_java",
|
|
"//components/android_autofill/browser:java",
|
|
"//components/autofill/android:autofill_features_java",
|
|
"//components/autofill/android:autofill_java",
|
|
@@ -1529,6 +1533,7 @@ if (_is_default_toolchain) {
|
|
"//chrome/test/data/translate/",
|
|
"//chrome/test/data/webauthn/",
|
|
"//chrome/test/media_router/resources/",
|
|
+ "//components/test/data/adblock/",
|
|
"//components/test/data/autofill/",
|
|
"//components/test/data/payments/",
|
|
"//content/test/data/browsing_data/",
|
|
@@ -3153,6 +3158,12 @@ if (_is_default_toolchain) {
|
|
sources += [ "java/src/org/chromium/chrome/browser/media/MediaCapturePickerManagerBridge.java" ]
|
|
}
|
|
|
|
+ ### Android API module start
|
|
+ sources +=
|
|
+ [ "java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java" ]
|
|
+
|
|
+ ### Android API module end
|
|
+
|
|
# Used for testing only, should not be shipped to end users.
|
|
if (enable_offline_pages_harness) {
|
|
sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
|
|
@@ -3244,6 +3255,7 @@ if (_is_default_toolchain) {
|
|
"//chrome/browser/ui/plus_addresses/android:jni_headers",
|
|
"//chrome/browser/util:jni_headers",
|
|
"//chrome/browser/webauthn/android:jni_headers",
|
|
+ "//components/adblock/android:jni_headers",
|
|
"//components/browser_ui/device_lock/android:device_lock_bridge_jni_headers",
|
|
"//components/content_relationship_verification/android:jni_headers",
|
|
"//components/image_fetcher:jni_headers",
|
|
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
|
|
--- a/chrome/android/chrome_java_sources.gni
|
|
+++ b/chrome/android/chrome_java_sources.gni
|
|
@@ -1,6 +1,9 @@
|
|
# Copyright 2019 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
+#
|
|
+# This source code is a part of eyeo Chromium SDK.
|
|
+# Use of this source code is governed by the GPLv3 that can be found in the components/adblock/LICENSE file.
|
|
|
|
import("//content/public/common/features.gni")
|
|
|
|
@@ -66,6 +69,7 @@ chrome_java_sources = [
|
|
"java/src/org/chromium/chrome/browser/accessibility/settings/ChromeAccessibilitySettingsDelegate.java",
|
|
"java/src/org/chromium/chrome/browser/actor/ActorForegroundServiceControllerImpl.java",
|
|
"java/src/org/chromium/chrome/browser/actor/ActorForegroundServiceImpl.java",
|
|
+ "java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java",
|
|
"java/src/org/chromium/chrome/browser/ai/AiAssistantService.java",
|
|
"java/src/org/chromium/chrome/browser/ai/PageSummaryButtonController.java",
|
|
"java/src/org/chromium/chrome/browser/ai/SystemAiProvider.java",
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java b/chrome/android/java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/adblock/TabIdTranslator.java
|
|
@@ -0,0 +1,36 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package chromium.chrome.browser.adblock;
|
|
+
|
|
+import org.jni_zero.NativeMethods;
|
|
+
|
|
+import org.chromium.content_public.browser.GlobalRenderFrameHostId;
|
|
+
|
|
+/**
|
|
+ * @brief Helper class to translate AdblockCounters.ResourceInfo.mMainFrameId to TabId.
|
|
+ */
|
|
+public final class TabIdTranslator {
|
|
+ public static int fromRenderFrameHostId(GlobalRenderFrameHostId id) {
|
|
+ return TabIdTranslatorJni.get().fromRenderFrameHostId(id.childId(), id.frameRoutingId());
|
|
+ }
|
|
+
|
|
+ @NativeMethods
|
|
+ public interface Natives {
|
|
+ int fromRenderFrameHostId(int renderProcessId, int renderFrameId);
|
|
+ }
|
|
+}
|
|
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
|
--- a/chrome/browser/BUILD.gn
|
|
+++ b/chrome/browser/BUILD.gn
|
|
@@ -3041,6 +3041,10 @@ static_library("browser") {
|
|
]
|
|
deps += [ "//chrome/browser/password_entry_edit/android" ]
|
|
|
|
+ ### Android API module start
|
|
+ sources += [ "android/adblock/tab_id_translator_jni.cc" ]
|
|
+ ### Android API module end
|
|
+
|
|
deps += [
|
|
":delta_file_proto",
|
|
":language_data_proto",
|
|
diff --git a/chrome/browser/android/adblock/tab_id_translator_jni.cc b/chrome/browser/android/adblock/tab_id_translator_jni.cc
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/chrome/browser/android/adblock/tab_id_translator_jni.cc
|
|
@@ -0,0 +1,43 @@
|
|
+/*
|
|
+ * 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/android/chrome_jni_headers/TabIdTranslator_jni.h"
|
|
+#include "chrome/browser/android/tab_android.h"
|
|
+#include "content/public/browser/web_contents.h"
|
|
+
|
|
+namespace {
|
|
+constexpr int kNoTabId = -1;
|
|
+}
|
|
+
|
|
+static jint JNI_TabIdTranslator_FromRenderFrameHostId(JNIEnv* env,
|
|
+ jint render_process_id,
|
|
+ jint render_frame_id) {
|
|
+ auto* web_contents = content::WebContents::FromRenderFrameHost(
|
|
+ content::RenderFrameHost::FromID(render_process_id, render_frame_id));
|
|
+ if (!web_contents) {
|
|
+ return kNoTabId;
|
|
+ }
|
|
+
|
|
+ auto* tab = TabAndroid::FromWebContents(web_contents);
|
|
+ if (!tab) {
|
|
+ return kNoTabId;
|
|
+ }
|
|
+
|
|
+ return tab->GetAndroidId();
|
|
+}
|
|
+
|
|
+DEFINE_JNI(TabIdTranslator)
|
|
diff --git a/components/adblock/android/BUILD.gn b/components/adblock/android/BUILD.gn
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/BUILD.gn
|
|
@@ -0,0 +1,107 @@
|
|
+# 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/>.
|
|
+
|
|
+import("//build/config/android/rules.gni")
|
|
+import("//build/config/locales.gni")
|
|
+import("//third_party/jni_zero/jni_zero.gni")
|
|
+import("//tools/grit/grit_rule.gni")
|
|
+
|
|
+source_set("java_bindings") {
|
|
+ sources = [
|
|
+ "adblock_controller_jni.cc",
|
|
+ "filtering_configuration_android.cc",
|
|
+ "filtering_configuration_android.h",
|
|
+ "resource_classification_notifier_android.cc",
|
|
+ "resource_classification_notifier_android.h",
|
|
+ ]
|
|
+ deps = [
|
|
+ ":jni_headers",
|
|
+ "//base",
|
|
+ "//components/keyed_service/content:content",
|
|
+ "//components/user_prefs:user_prefs",
|
|
+ ]
|
|
+
|
|
+ public_deps = [
|
|
+ "//components/adblock/content:browser",
|
|
+ "//components/adblock/core/configuration",
|
|
+ "//components/adblock/core/subscription",
|
|
+ "//components/prefs",
|
|
+ ]
|
|
+}
|
|
+
|
|
+generate_jni("jni_headers") {
|
|
+ sources = [
|
|
+ "java/src/org/chromium/components/adblock/AdblockController.java",
|
|
+ "java/src/org/chromium/components/adblock/FilteringConfiguration.java",
|
|
+ "java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java",
|
|
+ ]
|
|
+}
|
|
+
|
|
+android_library("adblock_controller_java") {
|
|
+ sources = [
|
|
+ "java/src/org/chromium/components/adblock/AdblockController.java",
|
|
+ "java/src/org/chromium/components/adblock/AdblockSwitches.java",
|
|
+ "java/src/org/chromium/components/adblock/ContentType.java",
|
|
+ "java/src/org/chromium/components/adblock/FilteringConfiguration.java",
|
|
+ "java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java",
|
|
+ "java/src/org/chromium/components/adblock/ResourceFilteringCounters.java",
|
|
+ ]
|
|
+
|
|
+ srcjar_deps = [ ":jni_headers" ]
|
|
+ deps = [
|
|
+ "//base:base_java",
|
|
+ "//content/public/android:content_java",
|
|
+ "//third_party/androidx:androidx_annotation_annotation_java",
|
|
+ "//third_party/jni_zero:jni_zero_java",
|
|
+ ]
|
|
+
|
|
+ resources_package = "org.chromium.components.adblock.controller"
|
|
+}
|
|
+
|
|
+android_library("adblock_java_tests_base") {
|
|
+ testonly = true
|
|
+ sources = [
|
|
+ "javatests/src/org/chromium/components/adblock/AdblockControllerTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/DefaultSettingsTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/FilteringConfigurationTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesCircumventionTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesCspTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesElemhideEmuInvTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesElemhideEmuTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesElemhideTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesExceptionTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesFilterTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesHeaderFilterTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesHelperBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesInlineCssTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesRemoveTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesRewriteTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesServiceWorkersTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesSiteKeyTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesSnippetsTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesWebsocketTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestPagesWildcardDomainTestBase.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestResourceFilteringObserver.java",
|
|
+ "javatests/src/org/chromium/components/adblock/TestVerificationUtils.java",
|
|
+ ]
|
|
+ deps = [
|
|
+ ":adblock_controller_java",
|
|
+ "//base:base_java",
|
|
+ "//base:base_java_test_support",
|
|
+ "//content/public/android:content_full_java",
|
|
+ "//content/public/test/android:content_java_test_support",
|
|
+ "//net/android:net_java_test_support",
|
|
+ "//third_party/androidx:androidx_test_monitor_java",
|
|
+ "//third_party/androidx:androidx_test_runner_java",
|
|
+ "//third_party/junit:junit",
|
|
+ ]
|
|
+}
|
|
diff --git a/components/adblock/android/adblock_controller_jni.cc b/components/adblock/android/adblock_controller_jni.cc
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/adblock_controller_jni.cc
|
|
@@ -0,0 +1,133 @@
|
|
+/*
|
|
+ * 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 <algorithm>
|
|
+#include <iterator>
|
|
+#include <vector>
|
|
+
|
|
+#include "base/android/jni_android.h"
|
|
+#include "base/android/jni_array.h"
|
|
+#include "base/android/jni_string.h"
|
|
+#include "base/android/jni_weak_ref.h"
|
|
+#include "base/logging.h"
|
|
+#include "components/adblock/android/jni_headers/AdblockController_jni.h"
|
|
+#include "components/adblock/content/browser/factories/subscription_service_factory.h"
|
|
+#include "components/adblock/core/common/adblock_constants.h"
|
|
+#include "components/adblock/core/subscription/subscription_config.h"
|
|
+#include "content/public/browser/android/browser_context_handle.h"
|
|
+#include "content/public/browser/browser_thread.h"
|
|
+
|
|
+using base::android::CheckException;
|
|
+using base::android::ConvertUTF8ToJavaString;
|
|
+using base::android::GetClass;
|
|
+using base::android::JavaParamRef;
|
|
+using base::android::MethodID;
|
|
+using base::android::ScopedJavaLocalRef;
|
|
+using base::android::ToJavaArrayOfObjects;
|
|
+using base::android::ToJavaArrayOfStrings;
|
|
+
|
|
+namespace {
|
|
+
|
|
+ScopedJavaLocalRef<jobject> ToJava(JNIEnv* env,
|
|
+ ScopedJavaLocalRef<jclass>& url_class,
|
|
+ jmethodID& url_constructor,
|
|
+ const std::string& url,
|
|
+ const std::string& title,
|
|
+ const std::string& version,
|
|
+ const std::vector<std::string>& languages,
|
|
+ const bool autoinstalled) {
|
|
+ ScopedJavaLocalRef<jobject> url_param =
|
|
+ ScopedJavaLocalRef<jobject>::Adopt(
|
|
+ env, env->NewObject(url_class.obj(), url_constructor,
|
|
+ ConvertUTF8ToJavaString(env, url).obj()));
|
|
+ CheckException(env);
|
|
+ return Java_Subscription_Constructor(env, url_param,
|
|
+ ConvertUTF8ToJavaString(env, title),
|
|
+ ConvertUTF8ToJavaString(env, version),
|
|
+ ToJavaArrayOfStrings(env, languages),
|
|
+ autoinstalled ? JNI_TRUE : JNI_FALSE);
|
|
+}
|
|
+
|
|
+std::vector<ScopedJavaLocalRef<jobject>> CSubscriptionsToJObjects(
|
|
+ JNIEnv* env,
|
|
+ const std::vector<scoped_refptr<adblock::Subscription>>& subscriptions) {
|
|
+ ScopedJavaLocalRef<jclass> url_class = GetClass(env, "java/net/URL");
|
|
+ jmethodID url_constructor = MethodID::Get<MethodID::TYPE_INSTANCE>(
|
|
+ env, url_class.obj(), "<init>", "(Ljava/lang/String;)V");
|
|
+ std::vector<ScopedJavaLocalRef<jobject>> jobjects;
|
|
+ jobjects.reserve(subscriptions.size());
|
|
+ for (auto& sub : subscriptions) {
|
|
+ jobjects.push_back(ToJava(
|
|
+ env, url_class, url_constructor, sub->GetSourceUrl().spec(),
|
|
+ sub->GetTitle(), sub->GetCurrentVersion(), std::vector<std::string>{},
|
|
+ sub->GetInstallationState() ==
|
|
+ adblock::InstalledSubscription::InstallationState::AutoInstalled));
|
|
+ }
|
|
+ return jobjects;
|
|
+}
|
|
+
|
|
+std::vector<ScopedJavaLocalRef<jobject>> CSubscriptionsToJObjects(
|
|
+ JNIEnv* env,
|
|
+ std::vector<adblock::KnownSubscriptionInfo>& subscriptions) {
|
|
+ ScopedJavaLocalRef<jclass> url_class = GetClass(env, "java/net/URL");
|
|
+ jmethodID url_constructor = MethodID::Get<MethodID::TYPE_INSTANCE>(
|
|
+ env, url_class.obj(), "<init>", "(Ljava/lang/String;)V");
|
|
+ std::vector<ScopedJavaLocalRef<jobject>> jobjects;
|
|
+ jobjects.reserve(subscriptions.size());
|
|
+ for (auto& sub : subscriptions) {
|
|
+ if (sub.ui_visibility == adblock::SubscriptionUiVisibility::Visible) {
|
|
+ // The checks here are when one makes f.e. adblock:custom visible
|
|
+ DCHECK(sub.url.is_valid());
|
|
+ if (sub.url.is_valid()) {
|
|
+ jobjects.push_back(ToJava(env, url_class, url_constructor,
|
|
+ sub.url.spec(), sub.title, "", sub.languages,
|
|
+ false));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return jobjects;
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+static base::android::ScopedJavaLocalRef<jobjectArray>
|
|
+JNI_AdblockController_GetInstalledSubscriptions(
|
|
+ JNIEnv* env,
|
|
+ const base::android::JavaParamRef<jobject>& jbrowser_context_handle) {
|
|
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
+ auto* subscription_service =
|
|
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle));
|
|
+ if (!subscription_service) {
|
|
+ return ToJavaArrayOfObjects(env,
|
|
+ std::vector<ScopedJavaLocalRef<jobject>>{});
|
|
+ }
|
|
+
|
|
+ return ToJavaArrayOfObjects(
|
|
+ env, CSubscriptionsToJObjects(
|
|
+ env, subscription_service->GetCurrentSubscriptions(
|
|
+ subscription_service->GetFilteringConfiguration(
|
|
+ adblock::kAdblockFilteringConfigurationName))));
|
|
+}
|
|
+
|
|
+static base::android::ScopedJavaLocalRef<jobjectArray>
|
|
+JNI_AdblockController_GetRecommendedSubscriptions(JNIEnv* env) {
|
|
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
+
|
|
+ auto list = adblock::config::GetKnownSubscriptions();
|
|
+ return ToJavaArrayOfObjects(env, CSubscriptionsToJObjects(env, list));
|
|
+}
|
|
diff --git a/components/adblock/android/filtering_configuration_android.cc b/components/adblock/android/filtering_configuration_android.cc
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/filtering_configuration_android.cc
|
|
@@ -0,0 +1,246 @@
|
|
+/*
|
|
+ * 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 "components/adblock/android/filtering_configuration_android.h"
|
|
+
|
|
+#include <iterator>
|
|
+#include <memory>
|
|
+
|
|
+#include "base/android/jni_android.h"
|
|
+#include "base/android/jni_array.h"
|
|
+#include "base/android/jni_string.h"
|
|
+#include "components/adblock/android/jni_headers/FilteringConfiguration_jni.h"
|
|
+#include "components/adblock/content/browser/factories/subscription_service_factory.h"
|
|
+#include "components/adblock/core/configuration/filtering_configuration.h"
|
|
+#include "components/adblock/core/configuration/persistent_filtering_configuration.h"
|
|
+#include "components/adblock/core/subscription/subscription_config.h"
|
|
+#include "components/user_prefs/user_prefs.h"
|
|
+#include "content/public/browser/android/browser_context_handle.h"
|
|
+
|
|
+using base::android::AttachCurrentThread;
|
|
+using base::android::ConvertJavaStringToUTF8;
|
|
+using base::android::ConvertUTF8ToJavaString;
|
|
+using base::android::JavaRef;
|
|
+using base::android::ScopedJavaLocalRef;
|
|
+using base::android::ToJavaArrayOfStrings;
|
|
+
|
|
+using namespace adblock;
|
|
+
|
|
+FilteringConfigurationAndroid::FilteringConfigurationAndroid(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jcontroller,
|
|
+ const std::string& configuration_name,
|
|
+ SubscriptionService* subscription_service,
|
|
+ PrefService* pref_service)
|
|
+ : subscription_service_(subscription_service),
|
|
+ pref_service_(pref_service),
|
|
+ java_weak_controller_(env, jcontroller) {
|
|
+ subscription_service_->AddObserver(this);
|
|
+ auto* existing_configuration =
|
|
+ subscription_service_->GetFilteringConfiguration(configuration_name);
|
|
+ if (existing_configuration) {
|
|
+ filtering_configuration_ptr = existing_configuration;
|
|
+ } else {
|
|
+ auto new_filtering_configuration =
|
|
+ std::make_unique<PersistentFilteringConfiguration>(pref_service_,
|
|
+ configuration_name);
|
|
+ filtering_configuration_ptr = new_filtering_configuration.get();
|
|
+ subscription_service_->InstallFilteringConfiguration(
|
|
+ std::move(new_filtering_configuration));
|
|
+ }
|
|
+ filtering_configuration_ptr->AddObserver(this);
|
|
+}
|
|
+
|
|
+FilteringConfigurationAndroid::~FilteringConfigurationAndroid() {
|
|
+ filtering_configuration_ptr->RemoveObserver(this);
|
|
+ subscription_service_->UninstallFilteringConfiguration(
|
|
+ filtering_configuration_ptr->GetName());
|
|
+ subscription_service_->RemoveObserver(this);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::Destroy(JNIEnv*) {
|
|
+ delete this;
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::OnEnabledStateChanged(
|
|
+ FilteringConfiguration* config) {
|
|
+ Notify(config, Java_FilteringConfiguration_enabledStateChanged);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::OnFilterListsChanged(
|
|
+ FilteringConfiguration* config) {
|
|
+ Notify(config, Java_FilteringConfiguration_filterListsChanged);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::OnAllowedDomainsChanged(
|
|
+ FilteringConfiguration* config) {
|
|
+ Notify(config, Java_FilteringConfiguration_allowedDomainsChanged);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::OnCustomFiltersChanged(
|
|
+ FilteringConfiguration* config) {
|
|
+ Notify(config, Java_FilteringConfiguration_customFiltersChanged);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::Notify(
|
|
+ FilteringConfiguration* config,
|
|
+ FilteringConfigurationAndroid::JavaEventListener event_listener_function) {
|
|
+ JNIEnv* env = AttachCurrentThread();
|
|
+ auto java_controller = java_weak_controller_.get(env);
|
|
+ if (!java_controller.is_null()) {
|
|
+ event_listener_function(env, java_controller);
|
|
+ }
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::OnSubscriptionInstalled(const GURL& url) {
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
+ JNIEnv* env = AttachCurrentThread();
|
|
+ ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec());
|
|
+ auto java_controller = java_weak_controller_.get(env);
|
|
+ if (!java_controller.is_null()) {
|
|
+ Java_FilteringConfiguration_onSubscriptionUpdated(env, java_controller,
|
|
+ j_url);
|
|
+ }
|
|
+}
|
|
+
|
|
+jboolean FilteringConfigurationAndroid::IsEnabled(JNIEnv* env) const {
|
|
+ return filtering_configuration_ptr->IsEnabled() ? JNI_TRUE : JNI_FALSE;
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::SetEnabled(JNIEnv* env,
|
|
+ jboolean j_enabled) {
|
|
+ filtering_configuration_ptr->SetEnabled(j_enabled == JNI_TRUE);
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::AddAllowedDomain(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& allowed_domain) {
|
|
+ filtering_configuration_ptr->AddAllowedDomain(
|
|
+ ConvertJavaStringToUTF8(allowed_domain));
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::RemoveAllowedDomain(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& allowed_domain) {
|
|
+ filtering_configuration_ptr->RemoveAllowedDomain(
|
|
+ ConvertJavaStringToUTF8(allowed_domain));
|
|
+}
|
|
+
|
|
+ScopedJavaLocalRef<jobjectArray>
|
|
+FilteringConfigurationAndroid::GetAllowedDomains(JNIEnv* env) const {
|
|
+ return ToJavaArrayOfStrings(env,
|
|
+ filtering_configuration_ptr->GetAllowedDomains());
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::AddCustomFilter(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& custom_filter) {
|
|
+ filtering_configuration_ptr->AddCustomFilter(
|
|
+ ConvertJavaStringToUTF8(custom_filter));
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::RemoveCustomFilter(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& custom_filter) {
|
|
+ filtering_configuration_ptr->RemoveCustomFilter(
|
|
+ ConvertJavaStringToUTF8(custom_filter));
|
|
+}
|
|
+
|
|
+ScopedJavaLocalRef<jobjectArray>
|
|
+FilteringConfigurationAndroid::GetCustomFilters(JNIEnv* env) const {
|
|
+ return ToJavaArrayOfStrings(env,
|
|
+ filtering_configuration_ptr->GetCustomFilters());
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::AddFilterList(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& url) {
|
|
+ filtering_configuration_ptr->AddFilterList(
|
|
+ GURL{ConvertJavaStringToUTF8(url)});
|
|
+}
|
|
+
|
|
+void FilteringConfigurationAndroid::RemoveFilterList(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jstring>& url) {
|
|
+ filtering_configuration_ptr->RemoveFilterList(
|
|
+ GURL{ConvertJavaStringToUTF8(url)});
|
|
+}
|
|
+
|
|
+ScopedJavaLocalRef<jobjectArray> FilteringConfigurationAndroid::GetFilterLists(
|
|
+ JNIEnv* env) const {
|
|
+ // For simplicity, convert GURL to std::string, pass to Java, and convert
|
|
+ // from String to URL. Strings are easier to pass through JNI.
|
|
+ std::vector<std::string> urls;
|
|
+ std::ranges::transform(filtering_configuration_ptr->GetFilterLists(),
|
|
+ std::back_inserter(urls), &GURL::spec);
|
|
+ return ToJavaArrayOfStrings(env, urls);
|
|
+}
|
|
+
|
|
+static ScopedJavaLocalRef<jstring>
|
|
+JNI_FilteringConfiguration_GetAcceptableAdsUrl(JNIEnv* env) {
|
|
+ return ConvertUTF8ToJavaString(env, adblock::AcceptableAdsUrl().spec());
|
|
+}
|
|
+
|
|
+static jlong JNI_FilteringConfiguration_Create(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jcontroller,
|
|
+ const JavaRef<jstring>& jstring,
|
|
+ const JavaRef<jobject>& jbrowser_context_handle) {
|
|
+ DCHECK(!jcontroller.is_null());
|
|
+ DCHECK(!jbrowser_context_handle.is_null());
|
|
+ auto* context =
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle);
|
|
+ return reinterpret_cast<jlong>(new FilteringConfigurationAndroid(
|
|
+ env, std::move(jcontroller), ConvertJavaStringToUTF8(jstring),
|
|
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(context),
|
|
+ user_prefs::UserPrefs::Get(context)));
|
|
+}
|
|
+
|
|
+static ScopedJavaLocalRef<jobjectArray>
|
|
+JNI_FilteringConfiguration_GetConfigurations(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jbrowser_context_handle) {
|
|
+ std::vector<std::string> configurations;
|
|
+ std::ranges::transform(
|
|
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle))
|
|
+ ->GetInstalledFilteringConfigurations(),
|
|
+ std::back_inserter(configurations),
|
|
+ [](adblock::FilteringConfiguration* fc) { return fc->GetName(); });
|
|
+ return ToJavaArrayOfStrings(env, configurations);
|
|
+}
|
|
+
|
|
+static jboolean JNI_FilteringConfiguration_IsAutoInstallEnabled(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jbrowser_context_handle) {
|
|
+ return adblock::SubscriptionServiceFactory::GetForBrowserContext(
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle))
|
|
+ ->IsAutoInstallEnabled()
|
|
+ ? JNI_TRUE
|
|
+ : JNI_FALSE;
|
|
+}
|
|
+
|
|
+static void JNI_FilteringConfiguration_SetAutoInstallEnabled(
|
|
+ JNIEnv* env,
|
|
+ jboolean j_enabled,
|
|
+ const JavaRef<jobject>& jbrowser_context_handle) {
|
|
+ adblock::SubscriptionServiceFactory::GetForBrowserContext(
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle))
|
|
+ ->SetAutoInstallEnabled(j_enabled == JNI_TRUE);
|
|
+}
|
|
+
|
|
+DEFINE_JNI(FilteringConfiguration)
|
|
diff --git a/components/adblock/android/filtering_configuration_android.h b/components/adblock/android/filtering_configuration_android.h
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/filtering_configuration_android.h
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * 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 COMPONENTS_ADBLOCK_ANDROID_FILTERING_CONFIGURATION_ANDROID_H_
|
|
+#define COMPONENTS_ADBLOCK_ANDROID_FILTERING_CONFIGURATION_ANDROID_H_
|
|
+
|
|
+#include <map>
|
|
+#include <utility>
|
|
+#include <vector>
|
|
+#include "base/android/jni_weak_ref.h"
|
|
+#include "base/memory/raw_ptr.h"
|
|
+#include "base/sequence_checker.h"
|
|
+#include "components/adblock/core/configuration/filtering_configuration.h"
|
|
+#include "components/adblock/core/subscription/subscription_service.h"
|
|
+#include "components/keyed_service/core/keyed_service.h"
|
|
+#include "components/prefs/pref_service.h"
|
|
+
|
|
+class FilteringConfigurationAndroid
|
|
+ : public adblock::FilteringConfiguration::Observer,
|
|
+ public adblock::SubscriptionService::SubscriptionObserver {
|
|
+ public:
|
|
+ explicit FilteringConfigurationAndroid(
|
|
+ JNIEnv* env,
|
|
+ const base::android::JavaRef<jobject>& jcontroller,
|
|
+ const std::string& configuration_name,
|
|
+ adblock::SubscriptionService* subscription_service,
|
|
+ PrefService* pref_service);
|
|
+ ~FilteringConfigurationAndroid() override;
|
|
+ // Called by Java to destroy this instance.
|
|
+ void Destroy(JNIEnv*);
|
|
+ void SetEnabled(JNIEnv* env, jboolean j_enabled);
|
|
+ jboolean IsEnabled(JNIEnv* env) const;
|
|
+ void AddFilterList(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& url);
|
|
+ void RemoveFilterList(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& url);
|
|
+ base::android::ScopedJavaLocalRef<jobjectArray> GetFilterLists(
|
|
+ JNIEnv* env) const;
|
|
+ void AddAllowedDomain(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& domain);
|
|
+ void RemoveAllowedDomain(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& domain);
|
|
+ base::android::ScopedJavaLocalRef<jobjectArray> GetAllowedDomains(
|
|
+ JNIEnv* env) const;
|
|
+ void AddCustomFilter(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& filter);
|
|
+ void RemoveCustomFilter(JNIEnv* env,
|
|
+ const base::android::JavaRef<jstring>& filter);
|
|
+ base::android::ScopedJavaLocalRef<jobjectArray> GetCustomFilters(
|
|
+ JNIEnv* env) const;
|
|
+
|
|
+ // FilteringConfiguration::Observer:
|
|
+ void OnEnabledStateChanged(adblock::FilteringConfiguration* config) override;
|
|
+ void OnFilterListsChanged(adblock::FilteringConfiguration* config) override;
|
|
+ void OnAllowedDomainsChanged(
|
|
+ adblock::FilteringConfiguration* config) override;
|
|
+ void OnCustomFiltersChanged(adblock::FilteringConfiguration* config) override;
|
|
+
|
|
+ // SubcriptionService::Observer:
|
|
+ void OnSubscriptionInstalled(const GURL& subscription_url) override;
|
|
+
|
|
+ private:
|
|
+ using JavaEventListener = void(JNIEnv* env,
|
|
+ const base::android::JavaRef<jobject>& obj);
|
|
+ void Notify(adblock::FilteringConfiguration* config,
|
|
+ JavaEventListener event_listener_function);
|
|
+ SEQUENCE_CHECKER(sequence_checker_);
|
|
+ raw_ptr<adblock::SubscriptionService> subscription_service_;
|
|
+ raw_ptr<PrefService> pref_service_;
|
|
+ raw_ptr<adblock::FilteringConfiguration> filtering_configuration_ptr;
|
|
+
|
|
+ // Direct reference to FilteringConfiguration java class. Kept for as
|
|
+ // long as this instance of FilteringConfigurationAndroid lives:
|
|
+ // until corresponding Profile gets destroyed. Destruction of Profile triggers
|
|
+ // destruction of both C++ FilteringConfigurationAndroid and Java
|
|
+ // FilteringConfiguration objects.
|
|
+ const JavaObjectWeakGlobalRef java_weak_controller_;
|
|
+};
|
|
+
|
|
+#endif // COMPONENTS_ADBLOCK_ANDROID_FILTERING_CONFIGURATION_ANDROID_H_
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/AdblockController.java b/components/adblock/android/java/src/org/chromium/components/adblock/AdblockController.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/AdblockController.java
|
|
@@ -0,0 +1,283 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+import androidx.annotation.UiThread;
|
|
+
|
|
+import org.jni_zero.CalledByNative;
|
|
+import org.jni_zero.NativeMethods;
|
|
+
|
|
+import org.chromium.base.ResettersForTesting;
|
|
+import org.chromium.base.ThreadUtils;
|
|
+import org.chromium.base.library_loader.LibraryLoader;
|
|
+import org.chromium.content_public.browser.BrowserContextHandle;
|
|
+
|
|
+import java.net.URL;
|
|
+import java.util.Arrays;
|
|
+import java.util.List;
|
|
+
|
|
+/**
|
|
+ * DEPRECATED, please use {@link FilteringConfiguration} instead.
|
|
+ *
|
|
+ * @brief Main access point for java UI code to control ad filtering. It calls its native counter
|
|
+ * part also AdblockController. It lives in UI thread on the browser process.
|
|
+ */
|
|
+@Deprecated
|
|
+public class AdblockController {
|
|
+ private static final String TAG = AdblockController.class.getSimpleName();
|
|
+ private FilteringConfiguration mFilteringConfiguration;
|
|
+ private BrowserContextHandle mBrowserContextHandle;
|
|
+
|
|
+ private URL mAcceptableAds;
|
|
+
|
|
+ private static AdblockController sInstance;
|
|
+
|
|
+ private AdblockController(BrowserContextHandle contextHandle) {
|
|
+ mBrowserContextHandle = contextHandle;
|
|
+ mFilteringConfiguration =
|
|
+ FilteringConfiguration.createConfiguration("adblock", mBrowserContextHandle);
|
|
+ try {
|
|
+ mAcceptableAds =
|
|
+ new URL("https://easylist-downloads.adblockplus.org/exceptionrules.txt");
|
|
+ } catch (java.net.MalformedURLException e) {
|
|
+ mAcceptableAds = null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The singleton object.
|
|
+ */
|
|
+ public static AdblockController getInstance(BrowserContextHandle contextHandle) {
|
|
+ // Make sure native libraries are ready to avoid org.chromium.base.JniException
|
|
+ LibraryLoader.getInstance().ensureInitialized();
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ if (sInstance == null) {
|
|
+ sInstance = new AdblockController(contextHandle);
|
|
+ }
|
|
+ return sInstance;
|
|
+ }
|
|
+
|
|
+ public static void setInstanceForTesting(final AdblockController adblockController) {
|
|
+ var oldValue = sInstance;
|
|
+ sInstance = adblockController;
|
|
+ ResettersForTesting.register(() -> sInstance = oldValue);
|
|
+ }
|
|
+
|
|
+ public static class Subscription {
|
|
+ private URL mUrl;
|
|
+ private String mTitle;
|
|
+ private String mVersion = "";
|
|
+ private String[] mLanguages = {};
|
|
+ private boolean mAutoInstalled;
|
|
+
|
|
+ public Subscription(final URL url, final String title, final String version) {
|
|
+ this.mUrl = url;
|
|
+ this.mTitle = title;
|
|
+ this.mVersion = version;
|
|
+ }
|
|
+
|
|
+ @CalledByNative("Subscription")
|
|
+ public Subscription(
|
|
+ final URL url,
|
|
+ final String title,
|
|
+ final String version,
|
|
+ final String[] languages,
|
|
+ boolean autoinstalled) {
|
|
+ this.mUrl = url;
|
|
+ this.mTitle = title;
|
|
+ this.mVersion = version;
|
|
+ this.mLanguages = languages;
|
|
+ this.mAutoInstalled = autoinstalled;
|
|
+ }
|
|
+
|
|
+ public String title() {
|
|
+ return mTitle;
|
|
+ }
|
|
+
|
|
+ public URL url() {
|
|
+ return mUrl;
|
|
+ }
|
|
+
|
|
+ public String version() {
|
|
+ return mVersion;
|
|
+ }
|
|
+
|
|
+ public String[] languages() {
|
|
+ return mLanguages;
|
|
+ }
|
|
+
|
|
+ public boolean autoinstalled() {
|
|
+ return mAutoInstalled;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(final Object object) {
|
|
+ if (object == null) return false;
|
|
+ if (getClass() != object.getClass()) return false;
|
|
+
|
|
+ Subscription other = (Subscription) object;
|
|
+ return url().equals(other.url());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void setAcceptableAdsEnabled(boolean enabled) {
|
|
+ if (enabled) mFilteringConfiguration.addFilterList(mAcceptableAds);
|
|
+ else mFilteringConfiguration.removeFilterList(mAcceptableAds);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public boolean isAcceptableAdsEnabled() {
|
|
+ return mFilteringConfiguration.getFilterLists().contains(mAcceptableAds);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public List<Subscription> getRecommendedSubscriptions() {
|
|
+ return (List<Subscription>)
|
|
+ (List<?>) Arrays.asList(AdblockControllerJni.get().getRecommendedSubscriptions());
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void setAutoInstallEnabled(boolean enable) {
|
|
+ FilteringConfiguration.setAutoInstallEnabled(enable, mBrowserContextHandle);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public boolean isAutoInstallEnabled() {
|
|
+ return FilteringConfiguration.isAutoInstallEnabled(mBrowserContextHandle);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void installSubscription(final URL url) {
|
|
+ mFilteringConfiguration.addFilterList(url);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void uninstallSubscription(final URL url) {
|
|
+ mFilteringConfiguration.removeFilterList(url);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public List<Subscription> getInstalledSubscriptions() {
|
|
+ return (List<Subscription>)
|
|
+ (List<?>)
|
|
+ Arrays.asList(
|
|
+ AdblockControllerJni.get()
|
|
+ .getInstalledSubscriptions(mBrowserContextHandle));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void setEnabled(boolean enabled) throws IllegalStateException {
|
|
+ mFilteringConfiguration.setEnabled(enabled);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public boolean isEnabled() throws IllegalStateException {
|
|
+ return mFilteringConfiguration.isEnabled();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeFilterList(final URL url) throws IllegalStateException {
|
|
+ mFilteringConfiguration.removeFilterList(url);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<URL> getFilterLists() throws IllegalStateException {
|
|
+ return mFilteringConfiguration.getFilterLists();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void addAllowedDomain(final String domain) throws IllegalStateException {
|
|
+ mFilteringConfiguration.addAllowedDomain(domain);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeAllowedDomain(final String domain) throws IllegalStateException {
|
|
+ mFilteringConfiguration.removeAllowedDomain(domain);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<String> getAllowedDomains() throws IllegalStateException {
|
|
+ return mFilteringConfiguration.getAllowedDomains();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void addCustomFilter(final String filter) throws IllegalStateException {
|
|
+ mFilteringConfiguration.addCustomFilter(filter);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeCustomFilter(final String filter) throws IllegalStateException {
|
|
+ mFilteringConfiguration.removeCustomFilter(filter);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<String> getCustomFilters() throws IllegalStateException {
|
|
+ return mFilteringConfiguration.getCustomFilters();
|
|
+ }
|
|
+
|
|
+ public interface SubscriptionUpdateObserver
|
|
+ extends FilteringConfiguration.SubscriptionUpdateObserver {}
|
|
+
|
|
+ @UiThread
|
|
+ public void addSubscriptionUpdateObserver(final SubscriptionUpdateObserver observer) {
|
|
+ mFilteringConfiguration.addSubscriptionUpdateObserver(observer);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void removeSubscriptionUpdateObserver(final SubscriptionUpdateObserver observer) {
|
|
+ mFilteringConfiguration.removeSubscriptionUpdateObserver(observer);
|
|
+ }
|
|
+
|
|
+ @NativeMethods
|
|
+ interface Natives {
|
|
+ Object[] getInstalledSubscriptions(BrowserContextHandle contextHandle);
|
|
+
|
|
+ Object[] getRecommendedSubscriptions();
|
|
+ }
|
|
+}
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/AdblockSwitches.java b/components/adblock/android/java/src/org/chromium/components/adblock/AdblockSwitches.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/AdblockSwitches.java
|
|
@@ -0,0 +1,22 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+public class AdblockSwitches {
|
|
+ public static final String DISABLE_EYEO_REQUEST_THROTTLING = "disable-eyeo-request-throttling";
|
|
+}
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/ContentType.java b/components/adblock/android/java/src/org/chromium/components/adblock/ContentType.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/ContentType.java
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.Map;
|
|
+
|
|
+public enum ContentType {
|
|
+ // Note. This has to be kept in sync with c++ enum so some values
|
|
+ // are skipped
|
|
+ CONTENT_TYPE_OTHER(1 << 0),
|
|
+ CONTENT_TYPE_SCRIPT(1 << 1),
|
|
+ CONTENT_TYPE_IMAGE(1 << 2),
|
|
+ CONTENT_TYPE_STYLESHEET(1 << 3),
|
|
+ CONTENT_TYPE_OBJECT(1 << 4),
|
|
+ CONTENT_TYPE_SUBDOCUMENT(1 << 5),
|
|
+ CONTENT_TYPE_WEBSOCKET(1 << 7),
|
|
+ CONTENT_TYPE_WEBRTC(1 << 8),
|
|
+ CONTENT_TYPE_PING(1 << 10),
|
|
+ CONTENT_TYPE_XMLHTTPREQUEST(1 << 11),
|
|
+ CONTENT_TYPE_MEDIA(1 << 14),
|
|
+ CONTENT_TYPE_FONT(1 << 15);
|
|
+
|
|
+ private final int contentType;
|
|
+
|
|
+ private ContentType(int contentType) {
|
|
+ this.contentType = contentType;
|
|
+ }
|
|
+
|
|
+ private static final Map<Integer, ContentType> intToContentTypeMap =
|
|
+ new HashMap<Integer, ContentType>();
|
|
+
|
|
+ static {
|
|
+ for (ContentType type : ContentType.values()) {
|
|
+ intToContentTypeMap.put(type.contentType, type);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static ContentType fromInt(int i) {
|
|
+ return intToContentTypeMap.get(i);
|
|
+ }
|
|
+
|
|
+ public int getValue() {
|
|
+ return contentType;
|
|
+ }
|
|
+}
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/FilteringConfiguration.java b/components/adblock/android/java/src/org/chromium/components/adblock/FilteringConfiguration.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/FilteringConfiguration.java
|
|
@@ -0,0 +1,424 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+import android.util.Log;
|
|
+import android.webkit.URLUtil;
|
|
+
|
|
+import androidx.annotation.UiThread;
|
|
+
|
|
+import org.jni_zero.CalledByNative;
|
|
+import org.jni_zero.NativeMethods;
|
|
+
|
|
+import org.chromium.base.ThreadUtils;
|
|
+import org.chromium.base.library_loader.LibraryLoader;
|
|
+import org.chromium.content_public.browser.BrowserContextHandle;
|
|
+
|
|
+import java.net.MalformedURLException;
|
|
+import java.net.URL;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Arrays;
|
|
+import java.util.Collections;
|
|
+import java.util.Comparator;
|
|
+import java.util.HashSet;
|
|
+import java.util.List;
|
|
+import java.util.Set;
|
|
+
|
|
+/**
|
|
+ * @brief Represents an independent configuration of filters, filter lists, allowed domains and
|
|
+ * other settings that influence resource filtering and content blocking. Multiple Filtering
|
|
+ * Configurations can co-exist and be controlled separately. A network resource is blocked if
|
|
+ * any enabled Filtering Configuration determines it should be, through its filters. Elements on
|
|
+ * websites are hidden according to a superset of element-hiding selectors from all enabled
|
|
+ * Filtering Configurations. Lives on UI thread, not thread-safe.
|
|
+ */
|
|
+public final class FilteringConfiguration {
|
|
+ private static final String TAG = FilteringConfiguration.class.getSimpleName();
|
|
+ private static final Set<FilteringConfiguration> mConfigurations = new HashSet<>();
|
|
+
|
|
+ private final Set<ConfigurationChangeObserver> mConfigurationChangeObservers = new HashSet<>();
|
|
+ private final Set<SubscriptionUpdateObserver> mSubscriptionUpdateObservers = new HashSet<>();
|
|
+ private String mName;
|
|
+ private long mNativeController;
|
|
+
|
|
+ private FilteringConfiguration(
|
|
+ final String configuration_name, BrowserContextHandle browserContextHandle) {
|
|
+ // Make sure native libraries are ready to avoid org.chromium.base.JniException
|
|
+ LibraryLoader.getInstance().ensureInitialized();
|
|
+
|
|
+ mName = configuration_name;
|
|
+ mNativeController =
|
|
+ FilteringConfigurationJni.get()
|
|
+ .create(this, configuration_name, browserContextHandle);
|
|
+ }
|
|
+
|
|
+ private void DestroyNative() {
|
|
+ FilteringConfigurationJni.get().destroy(mNativeController);
|
|
+ mNativeController = 0;
|
|
+ }
|
|
+
|
|
+ private void ValidateConfiguration() throws IllegalStateException {
|
|
+ if (mNativeController == 0) {
|
|
+ throw new IllegalStateException("Configuration does not exist!");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public interface ConfigurationChangeObserver {
|
|
+ /** Triggered when the FilteringConfiguration becomes disabled or enabled. */
|
|
+ @UiThread
|
|
+ void onEnabledStateChanged();
|
|
+
|
|
+ /** Triggered when the collection of installed filter lists changes. */
|
|
+ @UiThread
|
|
+ void onFilterListsChanged();
|
|
+
|
|
+ /** Triggered when the set of allowed domain changes. */
|
|
+ @UiThread
|
|
+ void onAllowedDomainsChanged();
|
|
+
|
|
+ /** Triggered when the set of custom filters changes. */
|
|
+ @UiThread
|
|
+ void onCustomFiltersChanged();
|
|
+ }
|
|
+
|
|
+ public interface SubscriptionUpdateObserver {
|
|
+ @UiThread
|
|
+ void onSubscriptionDownloaded(final URL url);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void addObserver(final ConfigurationChangeObserver observer) {
|
|
+ mConfigurationChangeObservers.add(observer);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void removeObserver(final ConfigurationChangeObserver observer) {
|
|
+ mConfigurationChangeObservers.remove(observer);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void addSubscriptionUpdateObserver(final SubscriptionUpdateObserver observer) {
|
|
+ mSubscriptionUpdateObservers.add(observer);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void removeSubscriptionUpdateObserver(final SubscriptionUpdateObserver observer) {
|
|
+ mSubscriptionUpdateObservers.remove(observer);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void setEnabled(boolean enabled) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ FilteringConfigurationJni.get().setEnabled(mNativeController, enabled);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public boolean isEnabled() throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ return FilteringConfigurationJni.get().isEnabled(mNativeController);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void addFilterList(final URL url) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ FilteringConfigurationJni.get().addFilterList(mNativeController, url.toString());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeFilterList(final URL url) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ FilteringConfigurationJni.get().removeFilterList(mNativeController, url.toString());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<URL> getFilterLists() throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ List<String> filterListsStr =
|
|
+ Arrays.asList(FilteringConfigurationJni.get().getFilterLists(mNativeController));
|
|
+ List<URL> filterLists = new ArrayList<URL>();
|
|
+ for (String url : filterListsStr) {
|
|
+ try {
|
|
+ filterLists.add(new URL(url));
|
|
+ } catch (MalformedURLException e) {
|
|
+ Log.e(TAG, "Received invalid subscription URL from C++: " + url);
|
|
+ }
|
|
+ }
|
|
+ return filterLists;
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public String getAcceptableAdsUrl() {
|
|
+ ValidateConfiguration();
|
|
+ return FilteringConfigurationJni.get().getAcceptableAdsUrl();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void addAllowedDomain(final String domain) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ String sanitizedDomain = sanitizeSite(domain);
|
|
+ if (sanitizedDomain == null) return;
|
|
+ FilteringConfigurationJni.get().addAllowedDomain(mNativeController, sanitizedDomain);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeAllowedDomain(final String domain) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ String sanitizedDomain = sanitizeSite(domain);
|
|
+ if (sanitizedDomain == null) return;
|
|
+ FilteringConfigurationJni.get().removeAllowedDomain(mNativeController, sanitizedDomain);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<String> getAllowedDomains() throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ List<String> allowedDomains =
|
|
+ Arrays.asList(FilteringConfigurationJni.get().getAllowedDomains(mNativeController));
|
|
+ Collections.sort(allowedDomains);
|
|
+ return allowedDomains;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void addCustomFilter(final String filter) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ FilteringConfigurationJni.get().addCustomFilter(mNativeController, filter);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public void removeCustomFilter(final String filter) throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ FilteringConfigurationJni.get().removeCustomFilter(mNativeController, filter);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @throws IllegalStateException when called on removed FilteringConfiguration.
|
|
+ */
|
|
+ @UiThread
|
|
+ public List<String> getCustomFilters() throws IllegalStateException {
|
|
+ ValidateConfiguration();
|
|
+ return Arrays.asList(FilteringConfigurationJni.get().getCustomFilters(mNativeController));
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public static FilteringConfiguration createConfiguration(
|
|
+ final String configuration_name, BrowserContextHandle browserContextHandle) {
|
|
+ FilteringConfiguration configuration = findConfigurationByName(configuration_name);
|
|
+ if (configuration == null) {
|
|
+ configuration = new FilteringConfiguration(configuration_name, browserContextHandle);
|
|
+ mConfigurations.add(configuration);
|
|
+ }
|
|
+ return configuration;
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public static void removeConfiguration(
|
|
+ final String configuration_name, BrowserContextHandle browserContextHandle) {
|
|
+ // sync with native filtering configurations
|
|
+ getConfigurations(browserContextHandle);
|
|
+ final FilteringConfiguration configuration = findConfigurationByName(configuration_name);
|
|
+ if (configuration != null) {
|
|
+ configuration.DestroyNative();
|
|
+ mConfigurations.remove(configuration);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public static List<FilteringConfiguration> getConfigurations(
|
|
+ BrowserContextHandle browserContextHandle) {
|
|
+ // Get all existing (on C++ side) configurations, if there is no matching Java
|
|
+ // instance present in mConfigurations set then create one and add.
|
|
+ final String[] existing_configurations_names =
|
|
+ FilteringConfigurationJni.get().getConfigurations(browserContextHandle);
|
|
+ final List<FilteringConfiguration> configurations_to_return =
|
|
+ new ArrayList<FilteringConfiguration>();
|
|
+ // If mConfigurations contains configurations which are not present on the list returned
|
|
+ // from FilteringConfigurationJni.get().getConfigurations() then we need to remove them
|
|
+ // as it means that a configuration has been removed on native side (not via Java API).
|
|
+ mConfigurations.removeIf(
|
|
+ filteringConfiguration -> {
|
|
+ return !Arrays.asList(existing_configurations_names)
|
|
+ .contains(filteringConfiguration.mName);
|
|
+ });
|
|
+ for (final String configuration_name : existing_configurations_names) {
|
|
+ FilteringConfiguration configuration = findConfigurationByName(configuration_name);
|
|
+ if (configuration == null) {
|
|
+ configuration =
|
|
+ new FilteringConfiguration(configuration_name, browserContextHandle);
|
|
+ mConfigurations.add(configuration);
|
|
+ }
|
|
+ configurations_to_return.add((FilteringConfiguration) configuration);
|
|
+ }
|
|
+ Collections.sort(
|
|
+ configurations_to_return,
|
|
+ new Comparator<FilteringConfiguration>() {
|
|
+ @Override
|
|
+ public int compare(
|
|
+ final FilteringConfiguration object1,
|
|
+ final FilteringConfiguration object2) {
|
|
+ return object1.mName.compareTo(object2.mName);
|
|
+ }
|
|
+ });
|
|
+ return configurations_to_return;
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ private static FilteringConfiguration findConfigurationByName(final String configuration_name) {
|
|
+ for (final FilteringConfiguration configuration : mConfigurations) {
|
|
+ if (configuration.mName.equals(configuration_name)) {
|
|
+ return configuration;
|
|
+ }
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public static void setAutoInstallEnabled(
|
|
+ boolean enable, BrowserContextHandle browserContextHandle) {
|
|
+ FilteringConfigurationJni.get().setAutoInstallEnabled(enable, browserContextHandle);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public static boolean isAutoInstallEnabled(BrowserContextHandle browserContextHandle) {
|
|
+ return FilteringConfigurationJni.get().isAutoInstallEnabled(browserContextHandle);
|
|
+ }
|
|
+
|
|
+ private String sanitizeSite(String site) {
|
|
+ // |site| is raw user input. We expect it to be either a domain or a URL.
|
|
+ try {
|
|
+ URL candidate = new URL(URLUtil.guessUrl(site));
|
|
+ return candidate.getHost();
|
|
+ } catch (java.net.MalformedURLException e) {
|
|
+ }
|
|
+ // Could not parse |site| as URL or domain.
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void enabledStateChanged() {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ for (final ConfigurationChangeObserver observer : mConfigurationChangeObservers) {
|
|
+ observer.onEnabledStateChanged();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void filterListsChanged() {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ for (final ConfigurationChangeObserver observer : mConfigurationChangeObservers) {
|
|
+ observer.onFilterListsChanged();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void allowedDomainsChanged() {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ for (final ConfigurationChangeObserver observer : mConfigurationChangeObservers) {
|
|
+ observer.onAllowedDomainsChanged();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void customFiltersChanged() {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ for (final ConfigurationChangeObserver observer : mConfigurationChangeObservers) {
|
|
+ observer.onCustomFiltersChanged();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void onSubscriptionUpdated(final String url) {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ try {
|
|
+ URL subscriptionUrl = new URL(URLUtil.guessUrl(url));
|
|
+ for (final SubscriptionUpdateObserver observer : mSubscriptionUpdateObservers) {
|
|
+ observer.onSubscriptionDownloaded(subscriptionUrl);
|
|
+ }
|
|
+ } catch (MalformedURLException e) {
|
|
+ Log.e(TAG, "Error parsing subscription url: " + url);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @NativeMethods
|
|
+ public interface Natives {
|
|
+ void destroy(long nativeFilteringConfigurationAndroid);
|
|
+
|
|
+ void setEnabled(long nativeFilteringConfigurationAndroid, boolean enabled);
|
|
+
|
|
+ boolean isEnabled(long nativeFilteringConfigurationAndroid);
|
|
+
|
|
+ void addAllowedDomain(long nativeFilteringConfigurationAndroid, String domain);
|
|
+
|
|
+ void removeAllowedDomain(long nativeFilteringConfigurationAndroid, String domain);
|
|
+
|
|
+ String[] getAllowedDomains(long nativeFilteringConfigurationAndroid);
|
|
+
|
|
+ void addCustomFilter(long nativeFilteringConfigurationAndroid, String filter);
|
|
+
|
|
+ void removeCustomFilter(long nativeFilteringConfigurationAndroid, String filter);
|
|
+
|
|
+ String[] getCustomFilters(long nativeFilteringConfigurationAndroid);
|
|
+
|
|
+ void addFilterList(long nativeFilteringConfigurationAndroid, String url);
|
|
+
|
|
+ void removeFilterList(long nativeFilteringConfigurationAndroid, String url);
|
|
+
|
|
+ String[] getFilterLists(long nativeFilteringConfigurationAndroid);
|
|
+
|
|
+ long create(
|
|
+ FilteringConfiguration controller,
|
|
+ final String configuration_name,
|
|
+ BrowserContextHandle contextHandle);
|
|
+
|
|
+ void setAutoInstallEnabled(boolean enable, BrowserContextHandle contextHandle);
|
|
+
|
|
+ boolean isAutoInstallEnabled(BrowserContextHandle contextHandle);
|
|
+
|
|
+ String[] getConfigurations(BrowserContextHandle contextHandle);
|
|
+
|
|
+ String getAcceptableAdsUrl();
|
|
+ }
|
|
+}
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java b/components/adblock/android/java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/ResourceClassificationNotifier.java
|
|
@@ -0,0 +1,233 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+import android.util.Log;
|
|
+
|
|
+import androidx.annotation.UiThread;
|
|
+
|
|
+import org.jni_zero.CalledByNative;
|
|
+import org.jni_zero.NativeMethods;
|
|
+
|
|
+import org.chromium.base.ThreadUtils;
|
|
+import org.chromium.base.library_loader.LibraryLoader;
|
|
+import org.chromium.content_public.browser.BrowserContextHandle;
|
|
+import org.chromium.content_public.browser.GlobalRenderFrameHostId;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Arrays;
|
|
+import java.util.HashSet;
|
|
+import java.util.List;
|
|
+import java.util.Set;
|
|
+
|
|
+public class ResourceClassificationNotifier {
|
|
+ private static final String TAG = ResourceClassificationNotifier.class.getSimpleName();
|
|
+
|
|
+ private long mNativeController;
|
|
+ private static ResourceClassificationNotifier sInstance;
|
|
+
|
|
+ private final Set<ResourceFilteringObserver> mResourceFilteringObservers = new HashSet<>();
|
|
+
|
|
+ // TODO(mpawlowski) in the future, we can consider adding filter hit
|
|
+ // notifications here as well (DPD-1233)
|
|
+
|
|
+ public interface ResourceFilteringObserver {
|
|
+ /**
|
|
+ * "Request allowed" event for a request which would be blocked but there was an
|
|
+ * allowlisting filter found.
|
|
+ *
|
|
+ * <p>It should not block the UI thread for too long.
|
|
+ *
|
|
+ * @param info contains auxiliary information about the resource.
|
|
+ */
|
|
+ @UiThread
|
|
+ void onRequestAllowed(ResourceFilteringCounters.ResourceInfo info);
|
|
+
|
|
+ /**
|
|
+ * "Request blocked" event for a request which was blocked.
|
|
+ *
|
|
+ * <p>It should not block the UI thread for too long.
|
|
+ *
|
|
+ * @param info contains auxiliary information about the resource.
|
|
+ */
|
|
+ @UiThread
|
|
+ void onRequestBlocked(ResourceFilteringCounters.ResourceInfo info);
|
|
+
|
|
+ /**
|
|
+ * "Page allowed" event for an allowlisted domain (page).
|
|
+ *
|
|
+ * <p>It should not block the UI thread for too long.
|
|
+ *
|
|
+ * @param info contains auxiliary information about the resource.
|
|
+ */
|
|
+ @UiThread
|
|
+ void onPageAllowed(ResourceFilteringCounters.ResourceInfo info);
|
|
+
|
|
+ /**
|
|
+ * "Popup allowed" event for a popup which would be blocked but there was an allowlisting
|
|
+ * filter found.
|
|
+ *
|
|
+ * <p>It should not block the UI thread for too long.
|
|
+ *
|
|
+ * @param info contains auxiliary information about the resource.
|
|
+ */
|
|
+ @UiThread
|
|
+ void onPopupAllowed(ResourceFilteringCounters.ResourceInfo info);
|
|
+
|
|
+ /**
|
|
+ * "Popup blocked" event for a popup which was blocked.
|
|
+ *
|
|
+ * <p>It should not block the UI thread for too long.
|
|
+ *
|
|
+ * @param info contains auxiliary information about the resource.
|
|
+ */
|
|
+ @UiThread
|
|
+ void onPopupBlocked(ResourceFilteringCounters.ResourceInfo info);
|
|
+ }
|
|
+
|
|
+ private ResourceClassificationNotifier(BrowserContextHandle contextHandle) {
|
|
+ mNativeController = ResourceClassificationNotifierJni.get().create(this, contextHandle);
|
|
+ assert mNativeController != 0
|
|
+ : "Failed to instantiate native ResourceClassificationNotifier";
|
|
+ }
|
|
+
|
|
+ public static ResourceClassificationNotifier getInstance(BrowserContextHandle contextHandle) {
|
|
+ // Make sure native libraries are ready to avoid org.chromium.base.JniException
|
|
+ LibraryLoader.getInstance().ensureInitialized();
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ if (sInstance == null) {
|
|
+ sInstance = new ResourceClassificationNotifier(contextHandle);
|
|
+ }
|
|
+ return sInstance;
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void addResourceFilteringObserver(final ResourceFilteringObserver observer) {
|
|
+ mResourceFilteringObservers.add(observer);
|
|
+ }
|
|
+
|
|
+ @UiThread
|
|
+ public void removeResourceFilteringObserver(final ResourceFilteringObserver observer) {
|
|
+ mResourceFilteringObservers.remove(observer);
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void requestMatchedCallback(
|
|
+ final String requestUrl,
|
|
+ boolean wasBlocked,
|
|
+ final String[] parentFrameUrls,
|
|
+ final String subscriptionUrl,
|
|
+ final String configurationName,
|
|
+ final int contentType,
|
|
+ final int renderProcessId,
|
|
+ final int renderFrameId) {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ final List<String> parentsList = Arrays.asList(parentFrameUrls);
|
|
+ final ResourceFilteringCounters.ResourceInfo resourceInfo =
|
|
+ new ResourceFilteringCounters.ResourceInfo(
|
|
+ requestUrl,
|
|
+ parentsList,
|
|
+ subscriptionUrl,
|
|
+ configurationName,
|
|
+ contentType,
|
|
+ new GlobalRenderFrameHostId(renderProcessId, renderFrameId));
|
|
+ Log.d(
|
|
+ TAG,
|
|
+ "eyeo: requestMatchedCallback() notifies "
|
|
+ + mResourceFilteringObservers.size()
|
|
+ + " listeners about "
|
|
+ + resourceInfo.toString()
|
|
+ + (wasBlocked ? " getting blocked" : " being allowed"));
|
|
+ for (final ResourceFilteringObserver observer : mResourceFilteringObservers) {
|
|
+ if (wasBlocked) {
|
|
+ observer.onRequestBlocked(resourceInfo);
|
|
+ } else {
|
|
+ observer.onRequestAllowed(resourceInfo);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void pageAllowedCallback(
|
|
+ final String requestUrl,
|
|
+ final String subscriptionUrl,
|
|
+ final String configurationName,
|
|
+ final int renderProcessId,
|
|
+ final int renderFrameId) {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ final ResourceFilteringCounters.ResourceInfo resourceInfo =
|
|
+ new ResourceFilteringCounters.ResourceInfo(
|
|
+ requestUrl,
|
|
+ new ArrayList(),
|
|
+ subscriptionUrl,
|
|
+ configurationName,
|
|
+ ContentType.CONTENT_TYPE_OTHER.getValue(),
|
|
+ new GlobalRenderFrameHostId(renderProcessId, renderFrameId));
|
|
+ Log.d(
|
|
+ TAG,
|
|
+ "eyeo: pageAllowedCallback() notifies "
|
|
+ + mResourceFilteringObservers.size()
|
|
+ + " listeners about "
|
|
+ + resourceInfo.toString());
|
|
+ for (final ResourceFilteringObserver observer : mResourceFilteringObservers) {
|
|
+ observer.onPageAllowed(resourceInfo);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @CalledByNative
|
|
+ private void popupMatchedCallback(
|
|
+ final String requestUrl,
|
|
+ boolean wasBlocked,
|
|
+ final String openerUrl,
|
|
+ final String subscription,
|
|
+ final String configurationName,
|
|
+ final int renderProcessId,
|
|
+ final int renderFrameId) {
|
|
+ ThreadUtils.assertOnUiThread();
|
|
+ final List<String> parentsList = Arrays.asList(openerUrl);
|
|
+ final ResourceFilteringCounters.ResourceInfo resourceInfo =
|
|
+ new ResourceFilteringCounters.ResourceInfo(
|
|
+ requestUrl,
|
|
+ parentsList,
|
|
+ subscription,
|
|
+ configurationName,
|
|
+ ContentType.CONTENT_TYPE_OTHER.getValue(),
|
|
+ new GlobalRenderFrameHostId(renderProcessId, renderFrameId));
|
|
+ Log.d(
|
|
+ TAG,
|
|
+ "eyeo: popupMatchedCallback() notifies "
|
|
+ + mResourceFilteringObservers.size()
|
|
+ + " listeners about "
|
|
+ + resourceInfo.toString()
|
|
+ + (wasBlocked ? " getting blocked" : " being allowed"));
|
|
+ for (final ResourceFilteringObserver observer : mResourceFilteringObservers) {
|
|
+ if (wasBlocked) {
|
|
+ observer.onPopupBlocked(resourceInfo);
|
|
+ } else {
|
|
+ observer.onPopupAllowed(resourceInfo);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @NativeMethods
|
|
+ public interface Natives {
|
|
+ // Create an instance of ResourceClassificationNotifier associated with the supplied
|
|
+ // profile.
|
|
+ long create(ResourceClassificationNotifier controller, BrowserContextHandle contextHandle);
|
|
+ }
|
|
+}
|
|
diff --git a/components/adblock/android/java/src/org/chromium/components/adblock/ResourceFilteringCounters.java b/components/adblock/android/java/src/org/chromium/components/adblock/ResourceFilteringCounters.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/java/src/org/chromium/components/adblock/ResourceFilteringCounters.java
|
|
@@ -0,0 +1,111 @@
|
|
+/*
|
|
+ * 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/>.
|
|
+ */
|
|
+
|
|
+package org.chromium.components.adblock;
|
|
+
|
|
+import org.chromium.content_public.browser.GlobalRenderFrameHostId;
|
|
+
|
|
+import java.util.List;
|
|
+
|
|
+public class ResourceFilteringCounters {
|
|
+ /** Immutable data-class containing an auxiliary information about resource event. */
|
|
+ public static class ResourceInfo {
|
|
+ // TODO: Make members private
|
|
+ final String mRequestUrl;
|
|
+ final List<String> mParentFrameUrls;
|
|
+ final String mSubscriptionUrl;
|
|
+ final String mConfigurationName;
|
|
+ final ContentType mContentType;
|
|
+ final GlobalRenderFrameHostId mMainFrameId;
|
|
+
|
|
+ ResourceInfo(
|
|
+ final String requestUrl,
|
|
+ final List<String> parentFrameUrls,
|
|
+ final String subscriptionUrl,
|
|
+ final String configurationName,
|
|
+ final int contentType,
|
|
+ final GlobalRenderFrameHostId mainFrameId) {
|
|
+ this.mRequestUrl = requestUrl;
|
|
+ this.mParentFrameUrls = parentFrameUrls;
|
|
+ this.mSubscriptionUrl = subscriptionUrl;
|
|
+ this.mConfigurationName = configurationName;
|
|
+ this.mContentType = ContentType.fromInt(contentType);
|
|
+ this.mMainFrameId = mainFrameId;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The request which was blocked or allowed.
|
|
+ */
|
|
+ public String getRequestUrl() {
|
|
+ return mRequestUrl;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The parent frames of the mRequestUrl.
|
|
+ */
|
|
+ public List<String> getParentFrameUrls() {
|
|
+ return mParentFrameUrls;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return Subscription url for filter done blocking or allowing decision, empty string
|
|
+ * otherwise.
|
|
+ */
|
|
+ public String getSubscription() {
|
|
+ return mSubscriptionUrl;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return Configuration name containing subscription with matched filer for blocking or
|
|
+ * allowing decision, empty string otherwise.
|
|
+ */
|
|
+ public String getConfigurationName() {
|
|
+ return mConfigurationName;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The resource content type. See enum ContentType in components/adblock/types.h
|
|
+ */
|
|
+ public ContentType getContentType() {
|
|
+ return mContentType;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The current tab id for the mRequestUrl. -1 means no tab id, likely tab closed
|
|
+ * before event arrived. Numbers start from 0.
|
|
+ */
|
|
+ public GlobalRenderFrameHostId getMainFrameId() {
|
|
+ return mMainFrameId;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return "mRequestUrl: "
|
|
+ + mRequestUrl
|
|
+ + ", mParentFrameUrls: "
|
|
+ + mParentFrameUrls.toString()
|
|
+ + ", mSubscriptionUrl:"
|
|
+ + mSubscriptionUrl
|
|
+ + ", mConfigurationName:"
|
|
+ + mConfigurationName
|
|
+ + ", mContentType: "
|
|
+ + mContentType.getValue()
|
|
+ + ", mMainFrameId: "
|
|
+ + mMainFrameId.frameRoutingId();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/components/adblock/android/resource_classification_notifier_android.cc b/components/adblock/android/resource_classification_notifier_android.cc
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/resource_classification_notifier_android.cc
|
|
@@ -0,0 +1,166 @@
|
|
+/*
|
|
+ * 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 "components/adblock/android/resource_classification_notifier_android.h"
|
|
+
|
|
+#include "base/android/jni_android.h"
|
|
+#include "base/android/jni_array.h"
|
|
+#include "base/android/jni_string.h"
|
|
+#include "base/android/jni_weak_ref.h"
|
|
+#include "components/adblock/content/browser/factories/resource_classification_runner_factory.h"
|
|
+#include "components/adblock/core/common/adblock_utils.h"
|
|
+#include "content/public/browser/android/browser_context_handle.h"
|
|
+#include "content/public/browser/render_process_host.h"
|
|
+#include "content/public/browser/web_contents.h"
|
|
+
|
|
+#include "components/adblock/android/jni_headers/ResourceClassificationNotifier_jni.h"
|
|
+
|
|
+using base::android::AttachCurrentThread;
|
|
+using base::android::ConvertUTF8ToJavaString;
|
|
+using base::android::JavaRef;
|
|
+using base::android::ScopedJavaLocalRef;
|
|
+using base::android::ToJavaArrayOfStrings;
|
|
+
|
|
+namespace adblock {
|
|
+
|
|
+ResourceClassificationNotifierAndroid::ResourceClassificationNotifierAndroid(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jcontroller,
|
|
+ ResourceClassificationRunner* classification_runner)
|
|
+ : classification_runner_(classification_runner),
|
|
+ java_weak_controller_(env, jcontroller) {
|
|
+ if (classification_runner_) {
|
|
+ classification_runner_->AddObserver(this);
|
|
+ }
|
|
+}
|
|
+
|
|
+ResourceClassificationNotifierAndroid::
|
|
+ ~ResourceClassificationNotifierAndroid() {
|
|
+ if (classification_runner_) {
|
|
+ classification_runner_->RemoveObserver(this);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ResourceClassificationNotifierAndroid::OnRequestMatched(
|
|
+ const GURL& url,
|
|
+ FilterMatchResult result,
|
|
+ const std::vector<GURL>& parent_frame_urls,
|
|
+ ContentType content_type,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) {
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
+ DCHECK(render_frame_host);
|
|
+ DCHECK(result == FilterMatchResult::kBlockRule ||
|
|
+ result == FilterMatchResult::kAllowRule);
|
|
+ const bool was_blocked = result == FilterMatchResult::kBlockRule;
|
|
+ DVLOG(3) << "[eyeo] Ad matched " << url << "(type: " << content_type
|
|
+ << (was_blocked ? ", blocked" : ", allowed") << ")";
|
|
+ JNIEnv* env = AttachCurrentThread();
|
|
+ auto java_controller = java_weak_controller_.get(env);
|
|
+ if (!java_controller.is_null()) {
|
|
+ ScopedJavaLocalRef<jstring> j_url =
|
|
+ ConvertUTF8ToJavaString(env, url.spec());
|
|
+ ScopedJavaLocalRef<jobjectArray> j_parents = ToJavaArrayOfStrings(
|
|
+ env, adblock::utils::ConvertURLs(parent_frame_urls));
|
|
+ ScopedJavaLocalRef<jstring> j_subscription =
|
|
+ ConvertUTF8ToJavaString(env, subscription.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_configuration =
|
|
+ ConvertUTF8ToJavaString(env, configuration_name);
|
|
+ const content::GlobalRenderFrameHostId rfh_id =
|
|
+ render_frame_host->GetGlobalId();
|
|
+ Java_ResourceClassificationNotifier_requestMatchedCallback(
|
|
+ env, java_controller, j_url, was_blocked, j_parents, j_subscription,
|
|
+ j_configuration, static_cast<int>(content_type), rfh_id.child_id.GetUnsafeValue(),
|
|
+ rfh_id.frame_routing_id);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ResourceClassificationNotifierAndroid::OnPageAllowed(
|
|
+ const GURL& url,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) {
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
+ DCHECK(render_frame_host);
|
|
+ DVLOG(3) << "[eyeo] Page allowed " << url;
|
|
+ JNIEnv* env = AttachCurrentThread();
|
|
+ auto java_controller = java_weak_controller_.get(env);
|
|
+ if (!java_controller.is_null()) {
|
|
+ ScopedJavaLocalRef<jstring> j_url =
|
|
+ ConvertUTF8ToJavaString(env, url.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_subscription =
|
|
+ ConvertUTF8ToJavaString(env, subscription.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_configuration =
|
|
+ ConvertUTF8ToJavaString(env, configuration_name);
|
|
+ const content::GlobalRenderFrameHostId rfh_id =
|
|
+ render_frame_host->GetGlobalId();
|
|
+ Java_ResourceClassificationNotifier_pageAllowedCallback(
|
|
+ env, java_controller, j_url, j_subscription, j_configuration,
|
|
+ rfh_id.child_id.GetUnsafeValue(), rfh_id.frame_routing_id);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ResourceClassificationNotifierAndroid::OnPopupMatched(
|
|
+ const GURL& url,
|
|
+ FilterMatchResult result,
|
|
+ const GURL& opener_url,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) {
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
+ DCHECK(render_frame_host);
|
|
+ DCHECK(result == FilterMatchResult::kBlockRule ||
|
|
+ result == FilterMatchResult::kAllowRule);
|
|
+ const bool was_blocked = result == FilterMatchResult::kBlockRule;
|
|
+ DVLOG(3) << "[eyeo] Popup matched " << url
|
|
+ << (was_blocked ? ", blocked" : ", allowed");
|
|
+ JNIEnv* env = AttachCurrentThread();
|
|
+ auto java_controller = java_weak_controller_.get(env);
|
|
+ if (!java_controller.is_null()) {
|
|
+ ScopedJavaLocalRef<jstring> j_url =
|
|
+ ConvertUTF8ToJavaString(env, url.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_opener =
|
|
+ ConvertUTF8ToJavaString(env, opener_url.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_subscription =
|
|
+ ConvertUTF8ToJavaString(env, subscription.spec());
|
|
+ ScopedJavaLocalRef<jstring> j_configuration =
|
|
+ ConvertUTF8ToJavaString(env, configuration_name);
|
|
+ const content::GlobalRenderFrameHostId rfh_id =
|
|
+ render_frame_host->GetGlobalId();
|
|
+ Java_ResourceClassificationNotifier_popupMatchedCallback(
|
|
+ env, java_controller, j_url, was_blocked, j_opener, j_subscription,
|
|
+ j_configuration, rfh_id.child_id.GetUnsafeValue(), rfh_id.frame_routing_id);
|
|
+ }
|
|
+}
|
|
+
|
|
+} // namespace adblock
|
|
+
|
|
+static jlong JNI_ResourceClassificationNotifier_Create(
|
|
+ JNIEnv* env,
|
|
+ const JavaRef<jobject>& jcontroller,
|
|
+ const base::android::JavaRef<jobject>& jbrowser_context_handle) {
|
|
+ DCHECK(!jcontroller.is_null());
|
|
+ DCHECK(!jbrowser_context_handle.is_null());
|
|
+ return reinterpret_cast<jlong>(
|
|
+ new adblock::ResourceClassificationNotifierAndroid(
|
|
+ env, std::move(jcontroller),
|
|
+ adblock::ResourceClassificationRunnerFactory::GetForBrowserContext(
|
|
+ content::BrowserContextFromJavaHandle(jbrowser_context_handle))));
|
|
+}
|
|
+
|
|
+DEFINE_JNI(ResourceClassificationNotifier)
|
|
diff --git a/components/adblock/android/resource_classification_notifier_android.h b/components/adblock/android/resource_classification_notifier_android.h
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/components/adblock/android/resource_classification_notifier_android.h
|
|
@@ -0,0 +1,72 @@
|
|
+/*
|
|
+ * 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 COMPONENTS_ADBLOCK_ANDROID_RESOURCE_CLASSIFICATION_NOTIFIER_ANDROID_H_
|
|
+#define COMPONENTS_ADBLOCK_ANDROID_RESOURCE_CLASSIFICATION_NOTIFIER_ANDROID_H_
|
|
+
|
|
+#include "base/android/jni_android.h"
|
|
+#include "base/android/jni_weak_ref.h"
|
|
+#include "components/adblock/content/browser/resource_classification_runner.h"
|
|
+#include "content/public/browser/browser_context.h"
|
|
+
|
|
+class FilterMatchResult;
|
|
+
|
|
+namespace adblock {
|
|
+
|
|
+class ResourceClassificationNotifierAndroid
|
|
+ : public ResourceClassificationRunner::Observer {
|
|
+ public:
|
|
+ ResourceClassificationNotifierAndroid(
|
|
+ JNIEnv* env,
|
|
+ const base::android::JavaRef<jobject>& jcontroller,
|
|
+ ResourceClassificationRunner* classification_runner);
|
|
+ ~ResourceClassificationNotifierAndroid() override;
|
|
+
|
|
+ // ResourceClassificationRunner::Observer
|
|
+ void OnRequestMatched(const GURL& url,
|
|
+ FilterMatchResult match_result,
|
|
+ const std::vector<GURL>& parent_frame_urls,
|
|
+ ContentType content_type,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) override;
|
|
+ void OnPageAllowed(const GURL& url,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) override;
|
|
+ void OnPopupMatched(const GURL& url,
|
|
+ FilterMatchResult match_result,
|
|
+ const GURL& opener_url,
|
|
+ content::RenderFrameHost* render_frame_host,
|
|
+ const GURL& subscription,
|
|
+ const std::string& configuration_name) override;
|
|
+
|
|
+ private:
|
|
+ SEQUENCE_CHECKER(sequence_checker_);
|
|
+ raw_ptr<ResourceClassificationRunner> classification_runner_;
|
|
+
|
|
+ // Direct reference to ResourceClassificationNotifier java class. Kept for as
|
|
+ // long as this instance of ResourceClassificationNotifierAndroid lives:
|
|
+ // until corresponding Profile gets destroyed. Destruction of Profile triggers
|
|
+ // destruction of both C++ ResourceClassificationNotifierAndroid and Java
|
|
+ // ResourceClassificationNotifier objects.
|
|
+ const JavaObjectWeakGlobalRef java_weak_controller_;
|
|
+};
|
|
+
|
|
+} // namespace adblock
|
|
+
|
|
+#endif // COMPONENTS_ADBLOCK_ANDROID_RESOURCE_CLASSIFICATION_NOTIFIER_ANDROID_H_
|
|
--
|