From b45c59b34ab729ec21e38d22587b7ef12cadabed Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 10:24:57 +0200 Subject: [PATCH] Respect per-app monitoring toggle when recording tracker access (#435) When "Manage system apps" is on and monitoring (the per-app `apply` toggle) is turned off for a system app such as the GPS daemon, the app list kept showing "contacted N companies last week" and the data reaccrued hours after clearing it. `shouldTrackApp()` gates whether tracker access is recorded via `updateAccess()` (ServiceSinkhole.java:988), and the app-list count is derived from those access rows. The gate checked tracker protection and `manage_system`, but never the `apply`/monitoring preference. Turning monitoring off adds the package to `addDisallowedApplication`, but traffic from system daemons sharing the app's UID can still reach the tunnel, so access rows kept being written under that UID and displayed on the monitoring-off app. Add an `apply` preference check to `shouldTrackApp()` (with a cached prefs handle refreshed in reload(), matching the existing tracker_protect pattern) so monitoring-off apps record no new tracker access. This mirrors the VPN-exclusion semantics already applied when `apply` is false and does not introduce any new setting. Co-Authored-By: Claude Fable 5 --- .../eu/faircode/netguard/ServiceSinkhole.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java b/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java index 8c1bc9daf..1ef03d83f 100644 --- a/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java +++ b/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java @@ -217,6 +217,7 @@ public class ServiceSinkhole extends VpnService { // Cached preferences for shouldTrackApp() - refreshed in reload() private volatile SharedPreferences cachedTrackerProtectPrefs; + private volatile SharedPreferences cachedApplyPrefs; private volatile boolean cachedManageSystem; private static final int NOTIFY_ENFORCING = 1; @@ -615,6 +616,7 @@ private void reload(boolean interactive) { // Refresh cached preferences for shouldTrackApp() cachedTrackerProtectPrefs = getSharedPreferences("tracker_protect", Context.MODE_PRIVATE); + cachedApplyPrefs = getSharedPreferences("apply", Context.MODE_PRIVATE); cachedManageSystem = prefs.getBoolean("manage_system", false); if (state != State.enforcing) { @@ -2340,7 +2342,8 @@ private Allowed isAddressAllowed(Packet packet) { /** * Check if tracking should be applied to this app (blocking/logging). * Returns false if: - * - Tracker Protection (apply) is disabled for this app + * - Monitoring (apply) is disabled for this app + * - Tracker Protection (tracker_protect) is disabled for this app * - It's a system app and manage_system is disabled */ private boolean shouldTrackApp(int uid) { @@ -2363,6 +2366,18 @@ private boolean shouldTrackApp(int uid) { uidToPackage.put(uid, packageName); } + // Check if monitoring is enabled for this app. When monitoring is off the + // app is excluded from the VPN (addDisallowedApplication), but traffic from + // system daemons sharing this UID can still reach the tunnel, so no tracker + // access must be recorded for it either. + SharedPreferences applyPrefs = cachedApplyPrefs; + if (applyPrefs == null) { + applyPrefs = getSharedPreferences("apply", Context.MODE_PRIVATE); + } + if (!applyPrefs.getBoolean(packageName, true)) { + return false; + } + // Check if tracker protection is enabled for this app SharedPreferences trackerProtectPrefs = cachedTrackerProtectPrefs; if (trackerProtectPrefs == null) {