LogoLogo
About GitLabAcceptable Ads
  • Getting Started
  • Browser Ad-Filtering Solution
    • Features
    • Getting Started
      • Quickstart
      • Integrate the Solution
      • Set up user counting
    • Guides
      • User counting
      • Configure Solution settings
      • Run separate instances of the filtering engine
      • Update the Solution
      • Understand the snippets library
      • Create a filter list
      • Testing
    • Advanced
      • Services and classes
      • Sitekey
      • ADRs
      • Frame hierarchy
  • Snippets
    • Snippets Overview
    • Behavioral Snippets
      • abort-current-inline-script
      • abort-on-property-read
      • abort-on-property-write
      • abort-on-iframe-property-read
      • abort-on-iframe-property-write
      • array-override
      • cookie-remover
      • freeze-element
      • json-override
      • json-prune
      • override-property-read
      • prevent-listener
      • replace-fetch-response
      • replace-xhr-response
      • simulate-mouse-event
      • skip-video
      • strip-fetch-query-parameter
    • Conditional Hiding Snippets
      • hide-if-canvas-contains
      • hide-if-contains
      • hide-if-contains-image
      • hide-if-contains-similar-text
      • hide-if-contains-visible-text
      • hide-if-contains-and-matches-style
      • hide-if-has-and-matches-style
      • hide-if-labelled-by
      • hide-if-matches-computed-xpath
      • hide-if-matches-xpath
      • hide-if-matches-xpath3
      • hide-if-shadow-contains
    • Debugging Snippets
      • debug
      • log
      • profile
      • trace
    • Performance Snippets
      • race
    • Snippets Support by Platform
    • Node Highlighting
    • Accessing shadow DOM elements
  • Working with filters
  • DATA AND PRIVACY
    • Data collection at eyeo
Powered by GitBook
On this page
  • The filtering engine is flexible
  • Filtering configuration
  • The default, ad-filtering configuration
  • Multiple filtering configurations
  • Interactions between filtering configurations
  • Creating a filtering configuration
  • Getting installed filtering configurations
  • Removing a filtering configuration
  • Enabling and disabling a configuration
  • Add/Remove filter lists
  • Observe filter list installation progress
  • Exempt a domain from filtering
  • Add/Remove custom filters
  • Subscribe to configuration change events
  • Observe resource classification

Was this helpful?

Edit on GitLab
Export as PDF
  1. Browser Ad-Filtering Solution
  2. Guides

Run separate instances of the filtering engine

Using multiple filtering configurations.

Last updated 4 months ago

Was this helpful?

The filtering engine is flexible

In the , you've learned how to configure ad-filtering. But the underlying filtering engine is more capable.

It could, for example:

  • block intrusive trackers,

  • block age-sensitive material,

  • filter geo-limited content,

  • remove arbitrary unwanted content from the user's browsing experience

As long as you can express the filtering demands via , you can probably use the Browser Ad-Filtering Solution to implement the behavior.

This section describes how to introduce new aspects of content filtering independently of ad-filtering.

Filtering configuration

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

Each filtering configuration has the following parameters:

Parameter
Description

Name

Unique name of this configuration

Enabled

Whether this entire configuration is currently enabled and active

Filter lists

List of currently selected filter lists, typically identified by URLs

Allowed domains

List of domains exempt from filtering

Custom filters

List of individual filters installed in addition to those from filter lists

The default, ad-filtering configuration

Multiple filtering configurations

Filtering configurations are independent, meaning each can be enabled, disabled or reconfigured separately from the others. Each maintains its own list of installed filter lists, custom filters and allowed domains.

Interactions between filtering configurations

What happens when one filtering configuration classifies a resource as blocked while another classifies it as allowed?

The blocking decision always wins.

This is a design decision. An example to rationalize it:

  • Perhaps filtering configuration adblock is an ad-filtering configuration and has a blanket rule to block every URL with an ad substring.

  • However, the user has allowlisted example.com by adding it to adblock's allowed domains, therefore filtering configuration adblock classifies https://example.com/ad.png as an allowed resource.

  • Filtering configuration sfw is an age-restricting configuration and it has a blocking filter for https://example.com/ad.png - not because it's an ad, but because it contains inappropriate content.

  • The blocking decision from filtering configuration sfw "wins", the inappropriate ad is blocked.

Creating a filtering configuration

Each filtering configuration must be installed on each browser start.

The configuration's settings are persistent and will be loaded upon installation.

import org.chromium.components.adblock.FilteringConfiguration;

// Creates "adblock" configuration if does not exist yet, returns a valid handle.
FilteringConfiguration myConfiguration = FilteringConfiguration.createConfiguration("my_configuration", browserContextHandle);
// No-op if configuration already exists.
chrome.eyeoFilteringPrivate.createConfiguration("my_configuration")
#include "chrome/browser/adblock/subscription_service_factory.h"
#include "components/adblock/core/configuration/persistent_filtering_configuration.h"
#include "components/adblock/core/subscription/subscription_service.h"

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

Getting installed filtering configurations

List<FilteringConfiguration> configs = FilteringConfiguration.getConfigurations();
// Without promises:
chrome.eyeoFilteringPrivate.getConfigurations(function(configs) {
  // configs = ['adblock', 'my_configuration']
  // 'adblock' installed by default.
  // 'my_configuration' installed by previous example.
});

// With promises:
await chrome.eyeoFilteringPrivate.getConfigurations().then(
    configs => {
        // configs = ['adblock', 'my_configuration']
    });
#include "chrome/browser/adblock/subscription_service_factory.h"
#include "components/adblock/core/configuration/filtering_configuration.h"
#include "components/adblock/core/subscription/subscription_service.h"

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

// "adblock" installed by default.
// "my_configuration" installed by previous example.
configurations[0]->GetName();  // "adblock"
configurations[1]->GetName();  // "my_configuration"

Removing a filtering configuration

You can remove filtering configuration if it is not needed. This means all associated preferences data will be removed.

FilteringConfiguration.removeConfiguration("my_configuration");

If you have FilteringConfirutation object for removed configuration, it becomes invalid. Any method called on a removed configuration will throw an IllegalStateException.

chrome.eyeoFilteringPrivate.removeConfiguration("my_configuration")
#include "chrome/browser/adblock/subscription_service_factory.h"
#include "components/adblock/core/subscription/subscription_service.h"

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

Enabling and disabling a configuration

By default, each configuration starts as enabled. If you disable it, the state persists and the configuration starts as disabled next time the browser runs.

The following example disables my_configuraion:

import org.chromium.components.adblock.FilteringConfiguration;

// myConfiguration created by previous example.

myConfiguration.isEnabled();  // true
myConfiguration.setEnabled(false);
myConfiguration.isEnabled();  // false
// "my_configuration" created by previous example.

// Without promises:
chrome.eyeoFilteringPrivate.isEnabled('my_configuration', function(enabled) {
  // enabled == true
});
// With promises:
chrome.eyeoFilteringPrivate.setEnabled('my_configuration', false)
    .then(
        () => {chrome.eyeoFilteringPrivate.isEnabled('my_configuration')
                   .then(
                       enabled => {
                           // enabled == false;
                       })});
#include "components/adblock/core/configuration/filtering_configuration.h"

FilteringConfiguration* my_configuration =
    ...;                        // Created or retrieved by previous examples.
my_configuration->IsEnabled();  // true
my_configuration->SetEnabled(false);
my_configuration->IsEnabled();  // false

Add/Remove filter lists

Observe filter list installation progress

When you add a filter list to a configuration, the configuration is updated instantly but the download and installation may take several seconds. If you want to be notified when an installation completes, you can register an observer.

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 created by previous example.
myConfiguration.addSubscriptionUpdateObserver(observer);

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

// Wait until download completes
// observer.onSubscriptionDownloaded("http://filters.com/list.txt") is called
// "my_configuration" created by previous example.
const filterList = 'http://filters.com/list.txt';

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

await chrome.eyeoFilteringPrivate.subscribeToFilterList(
    'my_configuration', filterList);

// Wait until download completes
// the listener is called
#include "components/adblock/core/configuration/filtering_configuration.h"
#include "components/adblock/core/subscription/subscription_service.h"

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

FilteringConfiguration* my_configuration =
    ...;  // Created or retrieved by previous examples.

Observer observer;
SubscriptionServiceFactory::GetForBrowserContext(profile())->AddObserver(
    &observer);

const GURL filter_list("http://filters.com/list.txt");
my_configuration->AddFilterList(filter_list);

// Wait until download completes
// Observer::OnSubscriptionInstalled is called

The Solution will also trigger this notification every time it successfully installs an update to the filter list, for example as a result of a scheduled, periodic update check.

Exempt a domain from filtering

To effectively disable all content filtering on a specific domain, add an allowed domain.

Remember, this allows all content on the domain, not from the domain. Adding trusted.org will let ads appear while the user is browsing https://www.trusted.org. But when the user is browsing https://example.com which attempts to load https://www.trusted.org/ads.js, the filtering still applies and the script might be blocked.

import org.chromium.components.adblock.FilteringConfiguration;

String allowedDomain = "trusted.org";

// myConfiguration created by previous example.
myConfiguration.addAllowedDomain(allowedDomain);

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

// The Solution will not filter any content on trusted.org.
// "my_configuration" created by previous example.
const allowed_domain = 'trusted.org';

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

// The Solution will not filter any content on trusted.org.
#include "components/adblock/core/configuration/filtering_configuration.h"

FilteringConfiguration* my_configuration =
    ...;  // Created or retrieved by previous examples.

const std::string allowed_domain = "trusted.org";
my_configuration->AddAllowedDomain(allowed_domain);

std::vector<std::string> allowed_domains =
    my_configuration->GetAllowedDomains();
// allowed_domains = ["trusted.org"]

// The Solution will not filter any content on trusted.org.

Add/Remove custom filters

Subscribe to configuration change events

If you'd like to be notified when some piece of code changes a filtering configuration, you may register an observer:

import org.chromium.components.adblock.FilteringConfiguration;

public class MyConfigurationChangeObserver
        implements FilteringConfiguration.ConfigurationChangeObserver {
    @Override
    public void onEnabledStateChanged() {
        // runs when someone calls setEnabled() to set a new state
    }
    @Override
    public void onFilterListsChanged() {
        // runs when someone adds or removes filter lists
    }
    @Override
    public void onAllowedDomainsChanged() {
        // runs when someone adds or removes allowed domains
    }
    @Override
    public void onCustomFiltersChanged() {
        // runs when someone adds or removes custom filters
    }
}

MyConfigurationChangeObserver observer = new MyConfigurationChangeObserver();

// myConfiguration created by previous example.
myConfiguration.addObserver(observer);

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

// observer.onFilterListsChanged() is called
// "my_configuration" created by previous example.
chrome.eyeoFilteringPrivate.onEnabledStateChanged.addListener(
    'my_configuration', function() {
      // runs when someone calls setEnabled() to set a new state
    });

chrome.eyeoFilteringPrivate.onFilterListsChanged.addListener(
    'my_configuration', function() {
      // runs when someone adds or removes filter lists
    });

chrome.eyeoFilteringPrivate.onAllowedDomainsChanged.addListener(
    'my_configuration', function() {
      // runs when someone adds or removes allowed domains
    });

chrome.eyeoFilteringPrivate.onCustomFiltersChanged.addListener(
    'my_configuration', function() {
      // runs when someone adds or removes custom filters
    });


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

// the second listener is called
#include "components/adblock/core/configuration/filtering_configuration.h"

class Observer : public FilteringConfiguration::Observer {
 public:
  void OnEnabledStateChanged(FilteringConfiguration* config) override {
    // runs when someone calls SetEnabled() to set a new state
  }
  void OnFilterListsChanged(FilteringConfiguration* config) override {
    // runs when someone adds or removes filter lists
  }
  void OnAllowedDomainsChanged(FilteringConfiguration* config) override {
    // runs when someone adds or removes allowed domains
  }
  void OnCustomFiltersChanged(FilteringConfiguration* config) override {
    // runs when someone adds or removes custom filters
  }
};

FilteringConfiguration* my_configuration =
    ...;  // Created or retrieved by previous examples.

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

const GURL filter_list("http://filters.com/list.txt");
my_configuration->AddFilterList(filter_list);

// Observer::OnFilterListsChanged is called

Observe resource classification

If you wish to be notified when network resources are blocked or allowed, register as an observer.

import org.chromium.components.adblock.ResourceClassificationNotifier;

public class MyClassificationObserver implements ResourceClassificationNotifier.AdBlockedObserver {
    @Override
    public void onAdAllowed(AdblockCounters.ResourceInfo info) {
        // Runs when a resource is specifically allowed by an
        // allowing filter from a filtering configuration
        // and isn't blocked by other filtering configurations.
    }
    @Override
    public void onAdBlocked(AdblockCounters.ResourceInfo info) {
        // Runs when a resource is blocked by a blocking filter
        // from at least one enabled filtering configuration.
    }
    @Override
    public void onPageAllowed(AdblockCounters.ResourceInfo info) {
        // Runs when every enabled filtering configuration exempts
        // this domain from filtering via allowed domains.
    }
    @Override
    public void onPopupAllowed(AdblockCounters.ResourceInfo info) {
        // Runs when a popup window is specifically allowed by an
        // allowing filter from a filtering configuration
        // and isn't blocked by other filtering configurations.
    }
    @Override
    public void onPopupBlocked(AdblockCounters.ResourceInfo info) {
        // Runs when a popup window is blocked by a blocking filter
        // from at least one enabled filtering configuration.
    }
}

MyClassificationObserver observer = new MyClassificationObserver();

ResourceClassificationNotifier.getInstance().addOnAdBlockedObserver(observer);
chrome.eyeoFilteringPrivate.onRequestAllowed.addListener(function(info) {
  // Runs when a resource is specifically allowed by an
  // allowing filter from a filtering configuration
  // and isn't blocked by other filtering configurations.
});
chrome.eyeoFilteringPrivate.onRequestBlocked.addListener(function(info) {
  // Runs when a resource is blocked by a blocking filter
  // from at least one enabled filtering configuration.
});
chrome.eyeoFilteringPrivate.onPageAllowed.addListener(function(info) {
  // Runs when every enabled filtering configuration exempts
  // this domain from filtering via allowed domains.
});
chrome.eyeoFilteringPrivate.onPopupAllowed.addListener(function(info) {
  // Runs when a popup window is specifically allowed by an
  // allowing filter from a filtering configuration
  // and isn't blocked by other filtering configurations.
});
chrome.eyeoFilteringPrivate.onPopupBlocked.addListener(function(info) {
  // Runs when a popup window is blocked by a blocking filter
  // from at least one enabled filtering configuration.
});

#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 void OnAdMatched(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 {
    if (match_result == FilterMatchResult::kAllowRule) {
      // Runs when a resource is specifically allowed by an
      // allowing filter from a filtering configuration
      // and isn't blocked by other filtering configurations.
    }
    if (match_result == FilterMatchResult::kBlockRule) {
      // Runs when a resource is blocked by a blocking filter
      // from at least one enabled filtering configuration.
    }
  }
  void void OnPageAllowed(const GURL& url,
                          content::RenderFrameHost* render_frame_host,
                          const GURL& subscription) override {
    // Runs when every enabled filtering configuration exempts
    // this domain from filtering via allowed domains.
  }
  void void OnPopupMatched(const GURL& url,
                           FilterMatchResult match_result,
                           const GURL& opener_url,
                           content::RenderFrameHost* render_frame_host,
                           const GURL& subscription) override {
    if (match_result == FilterMatchResult::kAllowRule) {
      // Runs when a popup window is specifically allowed by an
      // allowing filter from a filtering configuration
      // and isn't blocked by other filtering configurations.
    }
    if (match_result == FilterMatchResult::kBlockRule) {
      // Runs when a popup window is blocked by a blocking filter
      // from at least one enabled filtering configuration.
    }
  }
};

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

These settings are stored persistently in .

These parameters are very similar to the ones you encountered in the . In fact, the ad-filtering settings are implemented as a filtering configuration - with the name adblock. It is created by default in the Solution.

Filtering configurations allow dynamic management of filter lists identified by their URLs. To see implementation details for managing filter lists, refer to the .

If you need to allow all content from a domain, see .

Custom filters allow fine-tuning of filtering behavior by adding individual filters. For details on adding or removing custom filters, refer to the .

You don't observe a single filtering configuration because all installed filtering configurations take part in classification - see .

previous section
the filtering language
Preferences
Add/Remove custom filters
Interactions between filtering configurations
previous section
Configure SDK Settings guide
Configure SDK Settings guide