Skip to content

Commit 1532980

Browse files
committed
Charging: Record the HyperOS 3 candidate mapping from a device contribution
A Redmi Note 14 (tanzanite, Android 16, HyperOS 3) contribution report shows secure/security_pc_secure_protect_mode_key carrying a third value 2 = "Battery protection" alongside the HyperOS 2 values (0 = charge fully, 1 = intelligent). Docs and comments only: a candidate-mapping entry in the qualification ledger's known gaps, and the "no hard-cap mode exists" / "future HyperOS 3" statements scoped to HyperOS 2. No behavior change; HyperOS 3 stays diagnostics-only pending physical qualification.
1 parent d83688f commit 1532980

3 files changed

Lines changed: 27 additions & 8 deletions

File tree

.claude/skills/device-qualification/SKILL.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,19 @@ only after adding a row here. Detailed run narratives live in each adapter's lan
116116
battery monitoring across simulated plug/level transitions, and the charge alarm firing at threshold.
117117
- **Xiaomi** — adaptive hardware enforcement of external writes unconfirmed; treat the adapter as provisional until
118118
the 80% hold is physically observed.
119+
- **HyperOS 3 candidate mapping (contribution report, 2026-08-07 — unqualified, stays diagnostics-only).** A
120+
Redmi Note 14 `24117RN76G` (`tanzanite`, Android 16 / SDK 36, `ro.mi.os.version.code=3`, ROM
121+
`3.0.302.0.WOGMIXM.C08`) reported via the contribution wizard that the **same key**
122+
`secure/security_pc_secure_protect_mode_key` now carries **three** modes: `0` = Charge fully and
123+
`1` = Intelligent charging (labels matching HyperOS 2), plus a new `2` = **Battery protection** — apparently a
124+
hard-cap mode, which HyperOS 2 lacks entirely. The device correctly fell through to `XiaomiLabAdapter`, and the
125+
existing decode treats `2` as `Unknown(unrecognizedValue=true)` (refuse-don't-clobber — the test that pins this
126+
was written as a garbage-value guard; `2` is now known to be a real, named OEM mode). This is a settings mapping
127+
only: **no behavioral evidence** (the optional effect prompts were skipped), the cap percentage is unknown
128+
(modeling mode `2` needs a concrete `FixedLimit` percent), factory/absent-key semantics on HyperOS 3 are
129+
unknown, and whether value `2` is HyperOS-3-wide or model-specific is unconfirmed. A full qualification would
130+
also need the boundary write domain widened from `{"0","1"}` (`ChargingControlUserService`). The contributor
131+
has a working Shizuku setup (clean three-namespace, three-mode capture) — a strong candidate for a follow-up
132+
qualification run; the report thread is in support mail ("Amply device-support discovery", 2026-08-07).
119133
- **Pixel** — wireless at-threshold hold/charge-past and the widget under Shizuku-only remain unexercised (both share
120134
the verified wired mechanism).

.claude/skills/oem-adapters/SKILL.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ feature, not a per-model one): manufacturer Xiaomi (covers Redmi/POCO — they r
3636
manufacturer) + `ro.mi.os.version.code == 2` (HyperOS 2.x) + system user. Use `ro.mi.os.version.code`,
3737
NOT the frozen legacy `ro.miui.ui.version.code`. Single key
3838
`secure/security_pc_secure_protect_mode_key`: `0`=charge fully, `1`=Intelligent (heuristic 80% hold →
39-
`ChargePolicy.Adaptive`), absent=Intelligent (factory state). No hard-cap mode exists. SYNC_READBACK
39+
`ChargePolicy.Adaptive`), absent=Intelligent (factory state). No hard-cap mode exists **on HyperOS 2**; a
40+
HyperOS 3 contribution report (2026-08-07) shows the same key with a third value `2`="Battery protection" —
41+
a candidate hard-cap mode, unqualified (see the `device-qualification` skill). SYNC_READBACK
4042
with read-back equality; session override = Unrestricted; protective default = Adaptive. HyperOS 1,
41-
pre-HyperOS MIUI, and a future HyperOS 3 fall to `XiaomiLabAdapter` (diagnostics + contribution). Two
43+
pre-HyperOS MIUI, and HyperOS 3 fall to `XiaomiLabAdapter` (diagnostics + contribution). Two
4244
documented assumptions: the feature is treated as present on any HyperOS 2 device (a device lacking it
4345
reads the key absent → a harmless false claim of control), and daemon-level enforcement of external
4446
writes is pending long-term observation (see the `device-qualification` skill).

app/src/main/java/eu/darken/amply/charging/core/adapter/XiaomiChargingAdapter.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ import javax.inject.Singleton
1717
/**
1818
* Xiaomi HyperOS charging protection via `secure/security_pc_secure_protect_mode_key`
1919
* 0 = charge fully, 1 = "Intelligent charging" (heuristic
20-
* 80% hold decided by the OS — adaptive semantics, no hard cap exists). The key is absent in
21-
* factory state and the OEM UI treats absent as intelligent.
20+
* 80% hold decided by the OS — adaptive semantics, no hard cap exists on HyperOS 2). The key is
21+
* absent in factory state and the OEM UI treats absent as intelligent.
2222
*
2323
* The setting is a HyperOS ROM feature rather than a per-model one, so control is gated to the
2424
* HyperOS **major version** (2.x, from `ro.mi.os.version.code`) plus the Xiaomi manufacturer
2525
* (which also covers Redmi/POCO) and the system user (the secure namespace is per-user while
26-
* charging hardware is device-wide). HyperOS 1, pre-HyperOS MIUI, and a future HyperOS 3 fall
27-
* through to the diagnostics-only lab adapter until qualified.
26+
* charging hardware is device-wide). HyperOS 1, pre-HyperOS MIUI, and HyperOS 3 fall through to
27+
* the diagnostics-only lab adapter until qualified. A HyperOS 3 contribution report shows the
28+
* same key with an added value 2 = "Battery protection" (candidate hard cap, unqualified — see
29+
* the device-qualification ledger); the unrecognized-value decode below refuses it safely.
2830
*
2931
* Assumption (deliberate): the feature is treated as present on any HyperOS 2
3032
* device. A HyperOS 2 device that genuinely lacks Battery protection also reports the key absent,
@@ -111,8 +113,9 @@ class XiaomiChargingAdapter @Inject constructor() : ChargingAdapter {
111113
const val VALUE_CHARGE_FULLY = "0"
112114
const val VALUE_INTELLIGENT = "1"
113115

114-
// HyperOS 2.x (ro.mi.os.version.code). The mapping was verified on HyperOS 2.0; a future
115-
// HyperOS 3 stays unqualified until checked, mirroring the One UI range gates.
116+
// HyperOS 2.x (ro.mi.os.version.code). The mapping was verified on HyperOS 2.0; HyperOS 3
117+
// stays unqualified (reported to add value 2 = "Battery protection" — see the
118+
// device-qualification ledger), mirroring the One UI range gates.
116119
const val QUALIFIED_HYPEROS_VERSION = 2
117120
}
118121
}

0 commit comments

Comments
 (0)