CURRENT_NOW unit auto-calibration: show the real current on mA-unit devices (#152 v2)#170
Merged
Merged
Conversation
Kirin/HiSilicon reports CURRENT_NOW in mA instead of uA, so a real ~800 mA draw arrives as raw -800 and displayed as a nonsense "Discharging -1 mA" in the ongoing notification (and intermittently in the details table). Require the displayed current to round to at least MIN_DISPLAY_CURRENT_MA (10): the misread values cap out at ~1-3 "mA" and disappear, while on genuine-uA devices a sub-10 mA draw only happens in deep sleep, where nothing is being read anyway. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The same Kirin mA-unit misread flows into ChargeSpeed.powerMilliwatts (uA x mV / 1e6): a raw ~1000 while fast charging yields ~3-4 mW, which passed the > 0 check and classified as a known Trickle tier. That mislabeled the charge-connected announcement and the notification's charging segment as "Slow charging" (#125), and made SlowChargeDetector (#123) fire a false "check the cable and port" warning on every wired charge below 80%. A phone that reports CHARGING is never genuinely taking in under ~0.1 W, so add MIN_PLAUSIBLE_MW (100) as the mirror of the existing MAX_PLAUSIBLE_MW guard. Unknown power makes the tier displays fall back to the plain label and keeps the slow-charge detector asleep (its powerKnown gate). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…es (#152 v2) The floors in v1 stop garbage from being displayed, but on Kirin the current is simply hidden. Track the maximum |raw| CURRENT_NOW value ever observed (persisted across sessions): a genuine-uA device exceeds 20,000 (20 mA) within moments of awake use, while a mA-unit device physically cannot (that would be 20+ A). After enough spaced readings (60 at >= 1 min apart, >= 1 h cumulative) with the max still below the floor, conclude mA units and scale readings x1000 at the single read point (SystemService.getInstantaneousCurrentMicroAmps), so the rate tracker, the Current row, and ChargeSpeed all see the corrected value. Observation always records the raw (pre-scaling) value, so the conclusion cannot oscillate, and a later large reading voids it immediately and permanently in the same call. Preference writes are bounded: the max plateaus and counting stops at the cap. Needs on-device verification on the Mate 10 Pro before merging (expected raw magnitudes: ~200-2000 discharging, ~1000-2000 charging). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #169 (v1 floors) — review/merge that first; this PR's diff is just the calibration commit.
v1 stops the Kirin garbage from being displayed; this makes the readings correct there instead of hidden.
How it works
New
CurrentUnitCalibrator, hooked into the single read pointSystemService.getInstantaneousCurrentMicroAmps, so the rate tracker, the Current row, andChargeSpeedall see the same corrected value:CURRENT_NOWvalue ever observed (across sessions, charging and discharging alike).Safety properties:
Integer.MIN_VALUE/MAX_VALUE) and blank 0 pass through untouched.Side benefit: once calibrated, source A of the %/h rate (current ÷ capacity) works automatically with scaled current on any such device where capacity is known.
Known transient: at the moment the conclusion first flips on, the rate window still holds pre-scaling samples for up to 10 minutes; on Kirin source A is off anyway (capacity 0), so this is harmless and self-heals.
Tests
Pure helpers fully covered (
observefold: max tracking, spacing throttle, count cap, unchanged-instance contract;isMilliAmpUnitsboundaries at the floor and the sample cap; scaling incl. sign) plus Robolectric passthrough tests for the entry point.testDebugUnitTest+lintDebugpass.On-device verification needed before merging (Mate 10 Pro)
getIntProperty(CURRENT_NOW)Closes #152
🤖 Generated with Claude Code