Programs that respect your privacy

Android Filter Lists

Privacy Browser Android 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 Android.

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, *,*, and ** as being the same. In all cases, any URL that contains will be blocked.
  3. If the entry contains text separated by * it is broken into segments and each one is checked against the URL. For example, if the entry is*.jpg the URL will be checked to see if it contains both and .jpg. This could match against a few URLs not intended by the original block entry. For example, it would match against but also other URLs where the segments come in a different order like But the number of false positives should be small and the benefit in processing speed is significant.

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 are domain and third-party.

Lines that contain filter options preceded by ~ are inverse filter options. All of these are ignored except ~domain, which white lists the domain but applies the filter to other domains. Lines that contain ~third-party are ignored, because they typically are used to block the loading of some type of filter resource (script, xmlhttprequest, etc) from the main domain. Because Privacy Browser is not able to differentiate between these resources, if the block is applied it will block all resources from the domain, rendering it completely unusable. This is something that might be addressed in the future.

Lines that begin with @@ and contain ~domain filters are ignored because it is uncertain exactly what the two mean when combined.

Lines that begin with || begin checking against the beginning of the domain.  So || blocks but not or Implementing this logic correctly would be costly in terms of CPU processing, so Privacy Browser ignores || and processes the rest of the entry like any other.  This could lead to a small number of false positives.

Some lines contain ^, which is a separator wildcard that matches against :, /, ?, =, and &. These wildcards are ignored, which could lead to a small number of false positives as^ will match against intended URLs like and, but also unintended URLs like Once again, the performance gain is worth the very small number of false positives.

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.

The raw entries from the filter lists are processed into the following 22 ArrayLists used by Privacy Browser Android.  Each filter list has its own set of ArrayLists, which are checked in the following order.

  1. Main Allow List
  2. Final Allow List
  3. Domain Allow List
  4. Domain Initial Allow List
  5. Domain Final Allow List
  6. Third-Party Allow List
  7. Third-Party Domain Allow List
  8. Third-Party Domain Initial Allow List
  9. Main Block List
  10. Initial Block List
  11. Final Block List
  12. Domain Block List
  13. Domain Initial Block List
  14. Domain Final Block List
  15. Domain Regular Expression Block List
  16. Third-Party Block List
  17. Third-Party Initial Block List
  18. Third-Party Domain Block List
  19. Third-Party Domain Initial Block List
  20. Third-Party Regular Expression Block List
  21. Third-Party Domain Regular Expression Block List
  22. Regular Expression Block List

Initial lists check against the beginning of the URL. Final lists check against the end of the URL. Domain lists only check against certain domains. Third-party lists only apply if the root domain of the request is different than the root domain of the main URL. Regular expression lists follow the regular expression syntax. Each ArrayList item has one or more entry that derives from the original Adblock entry. In the case of domain ArrayLists, the resource request is only checked against the item if the first entry matches the domain of the main URL.

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

  1. EasyList
  2. EasyPrivacy
  3. Fanboy’s Annoyance List
  4. Fanboy’s Social Blocking List
  5. UltraList
  6. UltraPrivacy

If a resource matches against an allow list entry, the resource is allowed by that filter list and checking moves on to the following filter list.  If a resource matches against a block list entry, the loading of the resource is blocked by Privacy Browser Android and no more checking is performed.

Allow list entries on one list override block list entries on the same list but not on subsequent lists. For example, if a resource is allowed by an entry on EasyList, checking will move on to EasyPrivacy. If the same resource is blocked by an entry on EasyPrivacy, the loading of the resource will be blocked by Privacy Browser Android.

Privacy Browser has three additional filter lists. UltraList and UltraPrivacy filters ads and trackers that EasyList and EasyPrivacy do not. The third blocks all third-party requests. A request is only considered third-party if the base domain of the request is different than the base domain of the URL. For example, if loads a picture from, this is not blocked as a third-party request because they both share the same base domain of Blocking all third-party requests increases privacy, but this filter list is disabled by default because it breaks a large number of websites.

Android stores all assets (like the filter list data) in compressed files in the APK.  On a Pixel 5 running Android 13, decompressing and parsing the filter lists when Privacy Browser starts takes about half a second. Checking a resource URL against the lists takes about 20-50 milliseconds. On Android 14, which significantly nerfed performance in the quest for battery life, parsing the filter lists on a Pixel 5 takes about 3 seconds, and checking a resource URL against the lists takes about 100-200 milliseconds.

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

Last updated

2 responses to “Android Filter Lists”

  1. Avik D

    [Disclaimer : I’m not a tech person, but appreciate this browser by Stoutner ] Do the filter lists updated only when a new version of Privacy Browser in released? As far as I know, the Easylist and other filter lists get updated every few hours. Is there any way to update more frequently/on-demand the filter lists used by Privacy Browser?

    1. Soren Stoutner

      Sorry for the delayed response. I missed this comment at the time. The answer to your question can be found at

Leave a Reply