Skip to content

AppCleaner: Make deleted item count match the scanned count#2480

Merged
d4rken merged 1 commit into
mainfrom
worktree-appcleaner-count-align
Jun 22, 2026
Merged

AppCleaner: Make deleted item count match the scanned count#2480
d4rken merged 1 commit into
mainfrom
worktree-appcleaner-count-align

Conversation

@d4rken

@d4rken d4rken commented Jun 22, 2026

Copy link
Copy Markdown
Member

What changed

After cleaning with AppCleaner, the result could show far fewer "items deleted" than the scan reported as "found" — e.g. a scan finding 4876 items / 2.5 GB would show 80 items deleted / 2.6 GB freed. The freed space was correct and nothing was skipped, but the item counts looked wildly inconsistent and read like a bug.

The number now reflects the same thing the scan counted, so the "found" and "deleted" counts line up.

Technical Context

  • Root cause: the scan counts every expendable file individually (sum of AppJunk.itemCount), but the post-deletion result reported affectedPaths.size. On non-root devices, caches are cleared by the accessibility service tapping "Clear cache" per app — that whole-folder clear contributes only its ≤2 synthetic theoreticalPaths to affectedPaths, so hundreds of scanned files collapse to ~1–2 counted paths. Two incompatible counting scales, not data loss.
  • Fix: derive affectedCount from the before/after scan totals (snapshot.totalCount - internalData.totalCount) instead of affectedPaths.size. This reuses the exact counting the scan already does, so it can't drift from the "found" rules, and it counts ACS cache clears at scan scale. Chosen over a hand-rolled per-item counter (which would have to re-derive the accessible/inaccessible/public-cache rules and risk double-counting).
  • affectedPaths is left unchanged, so the stats path-record subsystem is unaffected. Side effect: the lifetime "items processed" stat stops undercounting ACS deletions, and the stats detail header now shows the true item count above the (inherently shorter) recordable-path list — accepted, since inaccessible cache files have no enumerable paths.
  • Propagated affectedCount through the OneClick and Scheduler success wrappers so background/one-tap runs report consistently too.
  • Review guidance: the count is a before/after snapshot diff taken under toolLock; coerceAtLeast(0) guards the (not-expected) negative case. Tests cover the ACS-cleared count, a failed clear (no overcount), includeInaccessible=false, and OneClick/Scheduler propagation.

The scan card counts every expendable file it finds (sum of AppJunk.itemCount),
but the post-deletion card showed affectedPaths.size. Caches cleared via the
accessibility-service "Clear cache" tap contribute only their <=2 synthetic
theoreticalPaths to affectedPaths, so a scan of e.g. 4876 found items could
report as ~80 deleted — same work, two incompatible counting scales.

Derive affectedCount from the pre/post-deletion scan totals
(snapshot.totalCount - internalData.totalCount) so it counts ACS cache clears
at scan scale instead of by recordable paths. affectedPaths is unchanged, so
stats path records are unaffected; the lifetime items-processed stat now stops
undercounting ACS deletions. Propagate affectedCount through the OneClick and
Scheduler success wrappers too.

Adds AppCleanerTest coverage for the ACS-cleared count, failed-clear (no
overcount), includeInaccessible=false, and OneClick/Scheduler propagation.
@d4rken d4rken added bug Something isn't working as expected c: AppCleaner c: Scheduler c: Stats Statistics, History and Reports labels Jun 22, 2026
@d4rken d4rken merged commit ba46788 into main Jun 22, 2026
24 of 25 checks passed
@d4rken d4rken deleted the worktree-appcleaner-count-align branch June 22, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working as expected c: AppCleaner c: Scheduler c: Stats Statistics, History and Reports

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant