Android Filter Lists

Privacy Browser uses the EasyList filter lists. EasyList is formatted using the Adblock syntax.

Privacy Browser Android features only a partial implementation of the Adblock feature set. Some of these limitations are required due to a lack of functionality exposed by WebView. In the future, with the release of Privacy WebView, some of these controls may be implemented. Other features are not implemented in the interest of performance on handheld devices.

Lines that begin with [ are headers and are ignored by Privacy Browser.

Lines that begin with ! are comments and are ignored except to extract the version number of the file.

Lines that begin with @@ are allowed and are processed according to the rules listed below.

Lines that begin with | match against the beginning of the URL.

Lines that end with | (or have entries that end with |) match against the end of the URL.

Lines that contain \ are regular expressions. Checking a regular expression against a URL is relatively expensive in terms of CPU consumption. Luckily, EasyList only contains a small number of regular expressions.

Lines that contain * could all be processed as regular expressions, but that would be a significant performance issue. Instead, they are processed in the following way:

  1. If the entry also contains \ it is processed as a regular expression.
  2. If the entry begins or ends with * the wildcard character is stripped out. These are redundant as the Adblock syntax defines example.com, *example.com, example.com*, and *example.com* as being the same. In all cases, any URL that contains example.com will be blocked.
  3. If the entry contains text separated by * it is broken into segments and each one is checked against the URL in order.

Lines that contain $ include filter options. Differentiating many of these would require access to more information than Android’s WebView exposes, and as such are ignored. The only two filter options that are processed by Privacy Browser Android are domain and third-party.

Lines that contain filter options preceded by ~ are inverse filter options. All of these are ignored except ~domain and ~third-party.

The AdBlock syntax envisions || blocking against the domain name or any subdomains thereof. For example, they consider ||example.com/banner.gif to block http://example.com/banner.gif, https://example.com/banner.gif, and https://www.example.com/banner.gif, but not https://badexample.com/banner.gif. For simplicity sake, Privacy Browser PC interprets || to match the beginning of the fully-qualified domain name, so ||example.com/banner.gif blocks http://example.com/banner.gif and https://example.com/banner.gif but not https://www.example.com/banner.gif or https://badexample.com/banner.gif.

Similarly, AdBlock envisions mixing applied and exempted domains, like domain=example.com|~foo.example.com. Privacy Browser PC’s implementation either applies or exempts all domains in the list based on the status of the first domain in the list (in practice, it doesn’t appear that any of the EasyList entries mix domains and excepted domains).

Some lines contain ^, which is a separator wildcard that matches against :, /, ?, =, and &.

Lines that contain ##, ###, ##., #?#, #@#, and #$# hide class, id, and name HTML and CSS elements in the code. Android’s WebView does not expose these types of controls and the lines are ignored by Privacy Browser Android.

Privacy Browser Android has three additional filter lists. UltraPrivacy and UltraList filters trackers and ads that EasyPrivacy and EasyList do not. The third blocks all third-party requests. Blocking all third-party requests increases privacy, but this filter list is disabled by default because it breaks a large number of websites.

Before a web page loads a resource, it is checked against the filter lists that are enabled in the following order:

  1. Block All Third-Party Requests
  2. UltraPrivacy
  3. UltraList
  4. EasyPrivacy
  5. EasyList
  6. Fanboy’s Annoyance List

The raw entries from the filter lists are processed into 6 sublists.

  1. Main Allow List
  2. Initial Domain Allow List
  3. Regular Expression Allow List
  4. Main Block List
  5. Initial Domain Block List
  6. Regular Expression Block List

Initial domain lists check against the beginning of the domain. These are very common and placing them in their own sublist allows for more CPU efficient checking of resource requests. Regular expression lists follow the regular expression syntax.

Each request is checked against the lists and sublists in the above order. If a match is found, the request is either allowed or blocked and subsequent processing is skipped. If no match is found, the Default - Allowed action is performed.

Android stores all assets (like the filter list data) in compressed files in the APK.  On a Pixel 8 running Android 16, decompressing and parsing the filter lists when Privacy Browser starts takes about one second. Checking a resource URL against the lists takes about 30-100 milliseconds per request. The checking is multi-threaded, so several resource requests can be checked simultaneously.

Further information about how the filter lists are parsed and applied can be found in the comments of the source code.

Originally posted:

Last updated: