Skip to content

Details refresh: in-place row updates, one system read per figure per tick (#161)#187

Merged
almothafar merged 1 commit into
masterfrom
fix/161-details-refresh-in-place
Jul 18, 2026
Merged

Details refresh: in-place row updates, one system read per figure per tick (#161)#187
almothafar merged 1 commit into
masterfrom
fix/161-details-refresh-in-place

Conversation

@almothafar

Copy link
Copy Markdown
Owner

Problem 1 — full table rebuild every 3 s

BatteryDetailsFragment now keeps its rows in a label-keyed registry and each refresh updates the value cells in place; rows are created/removed only when their label genuinely appears or vanishes (rate warm-up, time-to-full gating, capacity turning unknown). Accessibility focus, scroll position and the view tree survive refreshes.

Problem 2 — redundant system reads per tick

  • BatteryDO now carries the OS cycle count (EXTRA_CYCLE_COUNT, normalized to -1 like getChargeCycleCount) extracted from the same intent as everything else — pinned by SystemServiceTest.SnapshotCycleCount.
  • The fragment passes the snapshot''s capacity and cycle count into new BatteryHealthTracker overloads (isBatteryReadingUnreliable(context, mAh), getEffectiveCycleCount(context, osCycles)) — no second capacity estimate, no sticky re-read on the 3s tick.
  • Insights (updateHealthData) now does one sticky read + one capacity estimate per refresh, feeding everything through isCycleCountFromOs(osCycles), getMeasuredHealthPercentage(context, mAh) and the new pure cores estimatedHealthForCycles / gradeForCycles (parameterized tests pin the degradation curve and grade boundaries to each other).

Problem 3 — findViewById per tick in MainActivity

The gauge and the details fragment are fields set once in onCreate, like batteryInsightsButton already was; refreshBatteryUi, onPostResume, onPause, initializeFirstValues and the slider callback all use them.

Tests

testDebugUnitTest (407 tests, 24 new) + lintDebug green; debug build installed on the Mate 10 Pro.

On-device check: with the screen open, watch the details table across a few refreshes — values tick without the table flashing/scroll jumping, rate/time-to-full rows still come and go correctly, and the capacity "Unknown ⚠" affordance still opens its dialog.

Closes #161

🤖 Generated with Claude Code

…161)

Problem 1: every 3-second foreground tick tore the whole details table down
(removeAllViews) and rebuilt it, losing accessibility focus and churning
allocations. The table now keeps its rows keyed by label and updates the value
cells in place; rows are only created/removed when their key appears or
vanishes (rate warm-up, time-to-full gating). The diffing (syncRows) is a
static binder-driven helper with Robolectric tests.

Problem 2: redundant system reads per tick. BatteryDO now carries the OS cycle
count from the same intent everything else comes from; the fragment passes the
snapshot capacity and cycle count into new BatteryHealthTracker overloads
instead of re-reading BatteryManager and the sticky broadcast. Insights does
one sticky read and one capacity estimate per refresh, feeding pure
estimatedHealthForCycles/gradeForCycles cores.

Problem 3: MainActivity looked up the gauge (and details fragment) on every
tick/lifecycle hop; both are now fields set in onCreate.

Closes #161

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@almothafar
almothafar merged commit 8e395ba into master Jul 18, 2026
2 checks passed
@almothafar
almothafar deleted the fix/161-details-refresh-in-place branch July 18, 2026 09:52
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.

Details refresh: stop rebuilding the whole table every 3 s; cut redundant reads per tick

1 participant