Skip to content

Charging: session-relative drop detection for the slow-charge warning (v2 of #123) #132

Description

@almothafar

Backlog follow-up to #123 (slow/bad-cable warning). Depends on #123 — build v1 first; this extends its detector. Do not start until #123 has run on real devices for a while (see tuning note below).

What

Detect a large, sustained mid-session collapse in charging power: the session's best wattage was ~18 W, it's been stuck at ~2–5 W for the window — flag it even though the absolute level is ambiguous on its own.

Why (what v1 can't catch)

#123's v1 uses an absolute trickle floor (<~2.5 W), set below the weakest legitimate charger so it's nearly false-positive-free. The blind spot: a loose connector / partially-seated plug / failing cable on a good fast charger that still passes 5 W — above the v1 floor, so v1 stays silent, but 18 W → 5 W-and-stuck is suspicious. Only a relative comparison sees it.

Approach

  • Extend SlowChargeDetector (from Charging: slow / bad-cable warning #123) with per-session state: best sustained wattage seen this session (smoothed — a momentary peak must not become the baseline; consider "best average over any N-minute stretch").
  • Flag when current smoothed power stays below a conservative fraction of that baseline (starting point: >5× collapse, i.e. below ~20% of the session best) for the sustained window.
  • Reuse v1's whole guard set (status CHARGING, wired, level gate, hysteresis, once-per-session, observation-gap lapse rule) — this is an additional trigger inside the same detector, one alert channel/message family.
  • Session state resets on unplug (same lifecycle as v1's streak).

The benign-collapse traps (each needs an explicit guard or a threshold that clears it)

Charging power legitimately collapses mid-session; these are why v2 is not in v1:

  1. Thermal throttling — 25 W → 8 W when the phone warms or is used while charging. Consider correlating with battery temperature (we already read it): a collapse with rising/high temp is probably throttling → stay quiet.
  2. Charge-curve stepping — peak wattage only exists in the low-battery window; power steps down as cell voltage rises, well before 80%. Suggests a stricter level gate than v1 (e.g. only compare within <50–60%) and/or comparing against the best seen at a similar level.
  3. Adaptive / battery-care charging (Samsung adaptive, optimized charging) — deliberate mid-session slowdowns that don't always report NOT_CHARGING.
  4. System load — screen-on/gaming shrinks the battery's share of input power; consider only counting screen-off samples toward both baseline and collapse (we already have SystemService.isActivelyUsed).

The >5× starting threshold is chosen to clear traps 2–4 in most cases; trap 1 likely needs the temperature correlation.

Tuning prerequisite (why this waits for v1)

Thresholds here are guesses until real sessions are observed. Run #123's v1 on the Kirin Mate 10 Pro and the Samsung across normal charge sessions and note how wattage actually behaves (thermal dips, curve steps, adaptive slowdowns). Pick the collapse ratio, level gate, and temperature guard from that data — same ship-conservative-then-tune pattern as #108/#109.

Message

Distinct from v1's copy (different situation): v1 = "Charging slowly (~2 W) — check the cable and port."; v2 ≈ "Charging slowed from ~18 W to ~4 W — check the cable connection." Transparent style, real numbers, values-ar translation.

Acceptance criteria

  • Flags a sustained >Nx collapse vs the session's smoothed best, within the level gate
  • Stays silent through thermal throttling, charge-curve steps, adaptive charging, and screen-on load (guards above)
  • Shares v1's hysteresis / once-per-session / lapse-rule machinery — no parallel state
  • Thresholds tuned from observed real-device sessions before merge
  • Pure decision core unit-tested; strings in values-ar

Non-goals

  • Diagnosing the exact cause (cable vs port vs throttling is advisory-only via public APIs)
  • Wireless charging (alignment shifts make relative drops meaningless there — revisit separately if ever)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions