AdguardTeam / AdguardForAndroid

Open bug tracker for Android version of AdGuard.
https://adguard.com/
1.32k stars 90 forks source link

Automatically skip ads in apps using Accessibility Services #5092

Open ameshkov opened 10 months ago

ameshkov commented 10 months ago

Issue Details

We are somewhat limited in our ability to block ads in apps; achieving normal HTTPS filtering isn't feasible. Moreover, this isn't always sufficient to block in-app advertising (which often involves hardcoded pop-ups requiring user action to close them).

Proposed solution

We can attempt to use Accessibility Services to automatically close ad messages or skip ads. A good example is advertising on YouTube, which can be automatically skipped.

Declarative rules

It's crucial in this task not to simply hardcode some rules, but to provide the ability through our filtering system to set rules in a declarative mode, which will govern the new module. When designing this new type of rule, it is essential to consider that we may implement them on other platforms in the future.

Documentation

We also need to describe in our knowledge base the debugging tools that filter developers will need to use for studying the content of apps and automation (i.e., identifying element IDs, setting conditions for when to click, etc.).

What capabilities will the new type of rules have?

Accessibility Services generally allow the emulation of user actions: clicking on elements, reading element contents, turning sound on and off (useful on YouTube and Twitch to mute ad sound), etc. To understand the capabilities we need, we should first gather information on real applications where this could be useful.

@AdguardTeam/filters-maintainers please add examples of such apps in comments to these issues. You can link tasks from AdguardFilters for that.

Examples

  1. Youtube app. Whenever there's an ad playing, we can do the following: disable volume, wait for the "Skip Ads" button and tap it. Real-life example: https://github.com/alfeugds/adskipper/blob/main/app/src/main/java/com/alfeugds/adskipper/AdSkipperAccessibilityService.kt

  2. X (Twitter) app. Whenever there's an ad in the feed, we can automatically click "Not interested in this ad" and Twitter then will hide it.

Alternative solution

To be honest, I see no alternative solution to this approach for blocking hard-coded in-app ads.

ameshkov commented 10 months ago

Below is just an idea of how these declarative rules may look like.

!!! This is not a task yet, just an idea !!!

Generally, a declarative rule may look like this (kind of like scriptlet rules): [packageNames]#!#functionName(arguments).

Looking at the YT example, we can define two rules:

  1. When there's an element with a specified ID, mute media. The media should be unmuted if: YT is not in foreground anymore, there's no element with the specified ID anymore.
  2. When there's an element with the specified ID, click it.

A set of rules for YT:

com.android.youtube#!#muteIfExists('id/player_learn_more_button')
com.android.youtube#!#muteIfExists('id/skip_ad_button')
com.android.youtube#!#muteIfExists('id/ad_progress_text')
com.android.youtube#!#muteIfExists('id/app_promo_ad_cta_overlay')
com.android.youtube#!#muteIfExists('id/ad_countdown')
com.android.youtube#!#clickIfExists('id/skip_ad_button')
TPS commented 3 months ago

Definitely should remember https://github.com/AdguardTeam/AdguardForAndroid/issues/4010 while implementing this.