Skip to content

Show tracker activity that is recorded but currently undisplayable (#694) - #695

Draft
kasnder wants to merge 1 commit into
masterfrom
claude/trackercontrol-issue-694-2etv8g
Draft

Show tracker activity that is recorded but currently undisplayable (#694)#695
kasnder wants to merge 1 commit into
masterfrom
claude/trackercontrol-issue-694-2etv8g

Conversation

@kasnder

@kasnder kasnder commented Jul 29, 2026

Copy link
Copy Markdown
Member

Investigating #694 (Timeline blank while blocking and the Traffic Log work) surfaced two states in which tracker activity is recorded — or deliberately not recorded — but the Timeline gives no sign of it. Neither is confirmed as that reporter's root cause yet; both are real on their own.

1. UIDs without a resolvable package were dropped at display time

ServiceSinkhole.shouldTrackApp() defaults a UID whose package cannot be resolved to tracked ("Unknown UID, default to tracking"), so its tracker access is blocked and written to the access table. Both readers of that table then threw those rows away:

  • TimelineFragment.buildTimeline()if (appInfo == null || appInfo[1] == null) continue
  • InsightsDataProvider.computeInsights()if (packageName == null) continue

On Android 16 getPackagesForUid() throws SecurityException for UIDs belonging to another user — work profile, Secure Folder, private space, cloned apps — which Util.getPackagesForUid() maps to null (see #664). Activity from those apps was therefore recorded and permanently invisible, with no indication that anything had been hidden.

Now such entries are listed under an "Unidentified app (UID …)" label and counted in insights. They are not clickable, because the details screen is keyed by package name, and the per-package preference checks in insights (VPN exclusion, tracker protection) are skipped for them — mirroring what the recorder already does.

2. The empty state could not say that recording is off

With Search new trackers (log_app) disabled, trackers are still blocked but no access row is ever written, so the Timeline stays empty permanently — while showing "Watching for trackers…", which implies it will fill up. That is precisely the shape of #694: blocking works, the Traffic Log works (separate log pref), Timeline and all tracker counts stay at zero.

TimelineEmptyAdapter now distinguishes three states — TrackerControl off, recording off, watching — and the recording-off card links into settings so the user can recover.

Notes

  • The empty-state choice is a pure stateFor() helper with a unit test (TimelineEmptyStateTest).
  • No behaviour change to the recording path, the blocking path, or the database.
  • This environment has no Android SDK, so Gradle could not be run here; the Java sources were parse-checked with javac and the rest reviewed by hand. :app:compileGithubDebugJavaWithJavac and :app:testGithubDebugUnitTest still need a run on a machine with the SDK.

Generated by Claude Code

)

Two ways the Timeline can stay empty while tracker access is being
recorded and blocked normally.

Unresolvable UIDs were dropped at display time. ServiceSinkhole's
shouldTrackApp() deliberately defaults a UID whose package cannot be
resolved to tracked ("Unknown UID, default to tracking"), so its tracker
access is recorded and blocked — but both readers of the access table
then discarded those rows: TimelineFragment skipped entries without a
package name and InsightsDataProvider did the same. On Android 16
getPackagesForUid() throws SecurityException for UIDs of other users
(work profile, Secure Folder, private space, cloned apps), which Util
maps to null, so that activity was recorded and permanently invisible.
List it under a UID label instead; entries without a package are not
clickable, since the details screen is per package.

The empty state could not say that recording is off. With "Search new
trackers" (log_app) disabled, trackers are still blocked but no access
row is ever written, so the Timeline stays empty forever while claiming
"Watching for trackers…". Report that state separately and offer a way
into settings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkoZNtELmKmfNMxLump749
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants