Skip to content

Slow-charge warning: detect frayed cable / dying charger (#123)#150

Merged
almothafar merged 3 commits into
masterfrom
feat/123-slow-charge-warning
Jul 14, 2026
Merged

Slow-charge warning: detect frayed cable / dying charger (#123)#150
almothafar merged 3 commits into
masterfrom
feat/123-slow-charge-warning

Conversation

@almothafar

Copy link
Copy Markdown
Owner

Closes #123. The headline feature of the charger-notification redesign.

Top of the stack: #123#149 (#125) → #148 (#124) → #147 (lint). Bases retarget down as each merges.

What

Warns once per charge session when charging power stays abnormally low for a sustained time — a strong signal of a frayed cable, dirty/loose port, or dying charger.

How

New SlowChargeDetector, a pattern-copy of FastDrainDetector (#109): a pure, unit-tested decide() core + persisted streak/hysteresis state, evaluated on the battery broadcasts that already flow (no new timer). The signal is the estimated wattage from ChargeSpeed (#122, CURRENT_NOW × voltage).

Trigger: estimated power stays below a conservative trickle floor (~2.5 W wired) for a sustained window (3 min, a constant in v1) while charging below 80%.

Three guards keep it nearly false-positive-free (the traps from the issue):

Re-arms when power recovers above the floor or on disconnect.

Surfacing

Respects the #122 charge-notification style (toast / notification / none); the notification path uses the shared quiet-hours helper (#131) on its own channel + id 1641991. New enable toggle (default on) in the Charging settings category. The message is transparent — it states the measured wattage — and deliberately cant name cable vs port vs brick (indistinguishable via public APIs).

Verified

  • testDebugUnitTest + assembleDebug + lintDebug all green. New SlowChargeDetectorTest mirrors FastDrainDetectorTest (streak, once-per-session, re-arm, observation-gap lapse, floor boundary).
  • Installed on the Mate 10 Pro. New strings Arabic drafted — pending your review.

On-device check (your step)

Trickier to see naturally. Easiest with a bad/thin cable, or simulate via adb shell dumpsys battery set (level < 80, status charging) — but note the wattage comes from a real CURRENT_NOW, which dumpsys doesnt fake, so a real weak cable is the true test. ⚠️ On a device that doesnt report a usable CURRENT_NOW while charging, the power is unknown and it correctly stays silent (fail-quiet).

Not here

v2 — session-relative collapse (18 W → 4 W and stuck, which this absolute floor cant see) — stays in #132, which was waiting on real-device data from this v1.

🤖 Generated with Claude Code

@almothafar almothafar force-pushed the feat/125-charging-wattage-notification branch from 1e2715a to 3f5d8e3 Compare July 14, 2026 15:31
@almothafar almothafar force-pushed the feat/123-slow-charge-warning branch from 01f533e to 2b01566 Compare July 14, 2026 15:31
almothafar and others added 3 commits July 14, 2026 19:10
A single "Time to full · ~1h 20m" row directly below the charge rate,
shown only while charging with a trustworthy rate and below the taper
top (level < 99%) — hidden otherwise, so it never shows a garbage 0m.

Capacity-free linear projection from #108's smoothed charge rate:
(100 - level) / ratePercentPerHour, so it works on devices with an
unreliable charge counter (Kirin) too. Deliberately simple: no taper
modeling, precision is a non-goal (the OS owns the accurate figure).

New pure BatteryRateTracker.estimateMinutesToFull + a Western-digit
duration formatter. The estimate is unit-tested (level 99/100, rate 0/1,
rounding); the formatter is tested under Robolectric (~1h 20m / ~45m,
and Western digits even under the Arabic locale). New strings localized
in values-ar (units stay Latin like the other rate values).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
While charging, the ongoing status notification now shows the estimated
charge speed instead of %/h — "85% · Fast charging · ~18 W · 32.0 °C".
Charger speed is what people think in while plugged in; %/h stays the
right unit while discharging (unchanged).

statusWithRate gains a charging-only branch that reads getChargeSpeed
(CURRENT_NOW × voltage, from #122) and, when known, renders the tier +
wattage via the existing tierLabelRes mapping. The tier label already
reads as "… charging", so it replaces the plain "Charging" word rather
than doubling it. Falls back cleanly to the existing %/h → mA → plain
chain when the speed can't be estimated (e.g. a device without
CURRENT_NOW), so the discharging hot path is untouched.

Still gated by the existing show-rate preference — no new setting. One
new string (Western digits, #96) localized in values-ar. The ChargeSpeed
math is already covered by ChargeSpeedTest.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
New SlowChargeDetector warns once per charge session when the estimated
charging power (CURRENT_NOW x voltage, from #122) stays below a
conservative trickle floor (~2.5 W wired) for a sustained window
(3 min) — a strong signal of a frayed cable, dirty/loose port, or dying
charger.

Mirrors FastDrainDetector (#109): a pure, unit-tested decide() core plus
persisted streak/hysteresis state, evaluated on the battery broadcasts
(no new timer). Three guards keep it nearly false-positive-free:
- level < 80% (every charger deliberately tapers above ~80%)
- status == CHARGING (thermal/battery-protect pauses report
  NOT_CHARGING and are skipped, not cleared)
- wired only in v1 (wireless excluded)
Plus the #121 observation-gap lapse rule so a data gap can't inflate the
"sustained" claim. Re-arms when power recovers above the floor or on
disconnect.

Surfaced via the #122 charge-notification style (toast / notification /
none); the notification path uses the shared quiet-hours helper (#131)
on its own channel + id 1641991. Own enable toggle (default on) in the
Charging settings category. Transparent message shows the measured
wattage. New strings localized in values-ar.

v2 (session-relative collapse) stays in #132, not built here.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@almothafar almothafar force-pushed the feat/125-charging-wattage-notification branch from 3f5d8e3 to 0181454 Compare July 14, 2026 16:12
@almothafar almothafar force-pushed the feat/123-slow-charge-warning branch from 2b01566 to 6fddea8 Compare July 14, 2026 16:12
Base automatically changed from feat/125-charging-wattage-notification to master July 14, 2026 23:05
@almothafar almothafar merged commit bdefdbb into master Jul 14, 2026
1 check passed
@almothafar almothafar deleted the feat/123-slow-charge-warning branch July 14, 2026 23:06
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.

Charging: slow / bad-cable warning

1 participant