Filtering Configurations

Run Separate Instances of the Filtering Engine

Overview

The Browser Ad-Filtering Solution's filtering engine supports multiple independent filtering configurations beyond ad-blocking. Each configuration can manage distinct filtering rules for various purposes such as blocking trackers, age-restricting content, or filtering geo-limited material.

What is a Filtering Configuration?

A filtering configuration is a named, independent set of filtering options that are applied to network requests and website content. Each configuration includes:

Parameter

Purpose

Name

Unique identifier for the configuration

Enabled

Active status of the configuration

Filter lists

Selected filter lists by URL

Allowed domains

Domains exempt from filtering

Custom filters

Individual filters beyond filter lists

These settings persist using the browser's preferences system.

Key Architectural Features

Default Ad-Filtering Configuration

The system creates a default configuration named adblock automatically, implementing ad-filtering through the same filtering configuration framework.

Multiple Configuration Interactions

When multiple configurations evaluate the same resource, "the blocking decision always wins." This design ensures that if any enabled configuration blocks a resource, it remains blocked regardless of allow rules in other configurations.

Example scenario: An ad-filtering configuration may allowlist example.com, but a separate age-restriction configuration can still block specific resources from that domain if they contain inappropriate content.

Installation Requirements

Each filtering configuration must be installed on each browser start, though persistent settings load automatically upon installation.

Managing Filtering Configurations

Creating a Configuration

Java:

Java
import org.chromium.components.adblock.FilteringConfiguration;
FilteringConfiguration myConfiguration = 
    FilteringConfiguration.createConfiguration("my_configuration", browserContextHandle);

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.createConfiguration("my_configuration")

C++:

C++
#include "chrome/browser/adblock/subscription_service_factory.h"
#include "components/adblock/core/configuration/persistent_filtering_configuration.h"

auto my_configuration =
    std::make_unique<PersistentFilteringConfiguration>(
        profile()->GetPrefs(), "my_configuration");
SubscriptionServiceFactory::GetForBrowserContext(profile())
    ->InstallFilteringConfiguration(std::move(configuration));

Retrieving Installed Configurations

Java:

Java
List<FilteringConfiguration> configs = FilteringConfiguration.getConfigurations();

JavaScript:

JavaScript
// With promises:
await chrome.eyeoFilteringPrivate.getConfigurations().then(configs => {
    // configs = ['adblock', 'my_configuration']
});

C++:

C++
SubscriptionService* subscription_service =
    SubscriptionServiceFactory::GetForBrowserContext(profile());
const std::vector<FilteringConfiguration*> configurations =
    subscription_service->GetInstalledFilteringConfigurations();

Removing a Configuration

Java:

Java
FilteringConfiguration.removeConfiguration("my_configuration");

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.removeConfiguration("my_configuration")

C++:

C++
SubscriptionServiceFactory::GetForBrowserContext(profile())
    ->UninstallFilteringConfiguration("my_configuration");

Removing a configuration invalidates any existing object references and deletes all associated preferences data.

Enabling/Disabling Configurations

Configurations default to enabled status, with state persisting across browser sessions.

Java:

Java
myConfiguration.isEnabled();  // true
myConfiguration.setEnabled(false);
myConfiguration.isEnabled();  // false

JavaScript:

JavaScript
await chrome.eyeoFilteringPrivate.setEnabled('my_configuration', false)
    .then(() => {
        chrome.eyeoFilteringPrivate.isEnabled('my_configuration')
            .then(enabled => { /* enabled == false */ });
    });

C++:

C++
my_configuration->IsEnabled();  // true
my_configuration->SetEnabled(false);
my_configuration->IsEnabled();  // false

Filter List Management

Observing Installation Progress

Download and installation of filter lists may take several seconds. Register observers for completion notifications:

Java:

Java
import org.chromium.components.adblock.FilteringConfiguration;

public class MySubscriptionUpdateObserver
        implements FilteringConfiguration.SubscriptionUpdateObserver {
    @Override
    public void onSubscriptionDownloaded(final URL url) {
        // url == "http://filters.com/list.txt"
    }
}

MySubscriptionUpdateObserver observer = new MySubscriptionUpdateObserver();
myConfiguration.addSubscriptionUpdateObserver(observer);
myConfiguration.addFilterList(new URL("http://filters.com/list.txt"));

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.onSubscriptionUpdated.addListener(function(url) {
  // url == 'http://filters.com/list.txt'
});

await chrome.eyeoFilteringPrivate.subscribeToFilterList(
    'my_configuration', 'http://filters.com/list.txt');

C++:

C++
class Observer : public SubscriptionService::SubscriptionObserver {
 public:
  void OnSubscriptionInstalled(const GURL& subscription_url) override {
    // subscription_url == "http://filters.com/list.txt"
  }
};

Observer observer;
SubscriptionServiceFactory::GetForBrowserContext(profile())->AddObserver(&observer);
my_configuration->AddFilterList(GURL("http://filters.com/list.txt"));

The system also triggers notifications for periodic filter list updates.

Domain and Filter Management

Exempting Domains from Filtering

Adding an allowed domain disables filtering for content appearing on that domain, not content from that domain:

Java:

Java
String allowedDomain = "trusted.org";
myConfiguration.addAllowedDomain(allowedDomain);
List<String> allowedDomains = myConfiguration.getAllowedDomains();
// allowedDomains = ["trusted.org"]

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.addAllowedDomain('my_configuration', 'trusted.org');
chrome.eyeoFilteringPrivate.getAllowedDomains('my_configuration', function(domains) {
  // domains == ['trusted.org']
});

C++:

C++
my_configuration->AddAllowedDomain("trusted.org");
std::vector<std::string> allowed_domains = 
    my_configuration->GetAllowedDomains();

To allow content from a specific domain, use custom filters instead.

Configuration Change Events

Subscribing to Configuration Changes

Register observers to receive notifications when configurations are modified:

Java:

Java
public class MyConfigurationChangeObserver
        implements FilteringConfiguration.ConfigurationChangeObserver {
    @Override
    public void onEnabledStateChanged() { }
    @Override
    public void onFilterListsChanged() { }
    @Override
    public void onAllowedDomainsChanged() { }
    @Override
    public void onCustomFiltersChanged() { }
}

MyConfigurationChangeObserver observer = new MyConfigurationChangeObserver();
myConfiguration.addObserver(observer);
myConfiguration.addFilterList(new URL("http://filters.com/list.txt"));
// observer.onFilterListsChanged() is called

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.onEnabledStateChanged.addListener(
    'my_configuration', function() { });
chrome.eyeoFilteringPrivate.onFilterListsChanged.addListener(
    'my_configuration', function() { });
chrome.eyeoFilteringPrivate.onAllowedDomainsChanged.addListener(
    'my_configuration', function() { });
chrome.eyeoFilteringPrivate.onCustomFiltersChanged.addListener(
    'my_configuration', function() { });

C++:

C++
class Observer : public FilteringConfiguration::Observer {
 public:
  void OnEnabledStateChanged(FilteringConfiguration* config) override { }
  void OnFilterListsChanged(FilteringConfiguration* config) override { }
  void OnAllowedDomainsChanged(FilteringConfiguration* config) override { }
  void OnCustomFiltersChanged(FilteringConfiguration* config) override { }
};

Observer observer;
my_configuration->AddObserver(&observer);

Resource Classification Observation

Monitoring Resource Filtering Decisions

Observe when resources are blocked, allowed, or matched by filters across all installed configurations:

Java:

Java
import org.chromium.components.adblock.ResourceClassificationNotifier;

public class MyClassificationObserver implements 
    ResourceClassificationNotifier.ResourceFilteringObserver {
    @Override
    public void onRequestAllowed(ResourceFilteringCounters.ResourceInfo info) { }
    @Override
    public void onRequestBlocked(ResourceFilteringCounters.ResourceInfo info) { }
    @Override
    public void onPageAllowed(ResourceFilteringCounters.ResourceInfo info) { }
    @Override
    public void onPopupAllowed(ResourceFilteringCounters.ResourceInfo info) { }
    @Override
    public void onPopupBlocked(ResourceFilteringCounters.ResourceInfo info) { }
    @Override
    public void onPageElementMatched(ResourceFilteringCounters.PageElementInfo info) { }
}

MyClassificationObserver observer = new MyClassificationObserver();
ResourceClassificationNotifier.getInstance()
    .addResourceFilteringObserver(observer);

JavaScript:

JavaScript
chrome.eyeoFilteringPrivate.onRequestAllowed.addListener(function(RequestInfo info) { });
chrome.eyeoFilteringPrivate.onRequestBlocked.addListener(function(RequestInfo info) { });
chrome.eyeoFilteringPrivate.onPageAllowed.addListener(function(RequestInfo info) { });
chrome.eyeoFilteringPrivate.onPopupAllowed.addListener(function(RequestInfo info) { });
chrome.eyeoFilteringPrivate.onPopupBlocked.addListener(function(RequestInfo info) { });
chrome.eyeoFilteringPrivate.onPageElementMatched.addListener(function(PageElementInfo info) { });

C++:

C++
#include "chrome/browser/adblock/resource_classification_runner_factory.h"
#include "components/adblock/content/browser/resource_classification_runner.h"

class MyClassificationObserver : public ResourceClassificationRunner::Observer {
 public:
  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) override { }
  void OnPageAllowed(const GURL& url,
                     content::RenderFrameHost* render_frame_host,
                     const GURL& subscription) override { }
  void OnPopupMatched(const GURL& url,
                      FilterMatchResult match_result,
                      const GURL& opener_url,
                      content::RenderFrameHost* render_frame_host,
                      const GURL& subscription) override { }
  void OnPageElementMatched(const std::string& selector,
                            ElementHideAction action,
                            content::RenderFrameHost* render_frame_host) override { }
};

MyClassificationObserver observer;
ResourceClassificationRunnerFactory::GetForBrowserContext(profile())
    ->AddObserver(&observer);

The C++ implementation provides detailed selector information for element hiding filters, with selectors normalized to standardized formats.