Repository navigation
Releases: Rocker14427c/AXION-BS
Release list
Axion SPSM v3.10.0 - the measurement round + gesture navigation
The measurement round + gesture navigation. The phone was asked where the time goes (census: 6,354 calls in 488s of real use — the churn of per-app deep passes at every short screen-off is the cost, each call a JVM start), and the answers became code:
- deep_grace_secs (default 75) — per-app restrictions wait until the screen has stayed off; a 15-second screen-off never pays for them (~90% of the censused passes gone).
0restores v3.9.0 behavior. - Native
cmd settings/activity/packagepaths — a third of the JVM wrapper's cost under load, old commands kept as fallback. spsm-tool.jar— one JVM for a whole batch (the exit's 187 unstop calls included), suite-proven byte-equivalent to the fan, falls back to it on any doubtful answer.spsm-gesturemon(the gesture ask) — a native evdev recognizer that owns the bottom edge while the mode is on: swipe up = Axion home, hold = Axion recents, Pulse stays suspended (no second launcher, no extra drain). Zero CPU between touches, no grab — normal touches unaffected. Gated on gesture mode + the launcher actually being blocked by the mode; a gesture phone keeps its gestures for the session, every other phone gets the proven three-button path.
Deliberately NOT done (reasons in docs/ARCH-PERF-PLAN.md §4e): a C++ port of the transitions (the work is binder calls; once JVM starts are batched the shell orchestrates at syscall parity), private-API settings writes, evdev grab/uinput.
Honest ledger: suites green at this commit (732/0 main incl. new sections 92–95, codec, install 22/0, daemon 19/0); gesture semantics proven on the host through the same state machine the device runs; census measured on the device. Pending: the on-phone benchmark round + real-finger gesture proof (the tunnel died before they ran — numbers get appended to docs/RELEASE-v3.10.0.md). Every new path ships with its old path as fallback, so this is safe to flash meanwhile.
Flash: Axion-SPSM-v3.10.0-RMX3430.zip below (or release/ in the repo). Requires KernelSU. v3.9.0 (the field-measured daily round: ON 33s, OFF 21-24s, drift=0) remains the last fully device-benchmarked release.
Axion SPSM v3.9.0 - the daily round, measured
The daily round, measured: ON in 33s (was 67s) while doing more work, OFF in 21–24s (was 24–47s), and a journal that only claims what the phone confirmed.
Every number below was measured on the owner's phone (RMX3430, AxionOS, Android 16) on 2026-09-25, before and after — not estimated.
| the daily round | v3.8.2 (field, 10:59 / 12:17) | v3.9.0 (field, 13:54 / 13:58) |
|---|---|---|
| turning the mode ON | 67s with 13 knobs | 33s with 21 knobs (the full emergency posture) |
…of which block_other_apps |
41s | 7s |
| turning the mode OFF | 24–47s | 21–24s, three cycles in a row |
| …of which releasing 187 force-stopped apps | 14s | 4s |
| deep phase in (screen off) | 48s | 38s, and the freeze switches land last |
| deep phase out (wake) | 24s | 20s, thaw first |
| exit verification | — | checked=27 drift=0 left-alone=0 on every cycle |
| journal after 187 confirmed suspensions | "no visible change" — false | 187 × suspended, from pm's own confirmation |
What the field log said
The morning log was the specification for this release:
SPSM ON: 13 knobs applied in 67s— and 41 of those seconds were the one knob that blocks
background apps. Inside it: 6s building the candidate list, 9s force-stopping, 10s writing the
record, and two full re-reads of the package list around the whole thing.revert clean in 47s— a third of it one loop releasing 187 force-stopped packages, onepm
call at a time.note block_other_apps: no visible change (optional node missing?)— logged while
state/blocked_by_us.tsvheld 187 packages pm had just confirmed suspended. The after-read
raced PackageManager's disk flush and the journal called a real change invisible.- A progress file reading "Idle: applying the asleep options" still on disk 26 minutes after the
phone woke, and 34 empty scratch directories a day in.tmp/. - The home swap re-applying itself about a minute after activation, because the session tail did
not ask the journal whether the work was already done.
Turning ON: the same honesty, a sixth of the waiting
The block knob, 41s → 7s, culprit by culprit:
- One package list per run. A single activation built the blockable list three times
(before-snapshot, candidates, after-snapshot), each build costing the protected-role binder
round trips plus twopm listcalls. The build is now cached under the run's id and published
where the run's later callers read it; the after-read does not list packages at all. The run
even pre-warms the cache in the background at the top of the activation, so the first reader
finds it built. (Measured on the device: build 246ms quiet, cache hit ~0ms.) - The before-snapshot trusts the phone's own record. When
package-restrictions.xml— the
file pm itself uses — was read and says nothing is suspended, that is the answer; the old code
double-checked it with adumpsys packageper candidate, 188 binder round trips, ~8s of
every activation. The per-package check still runs on the phones where the record cannot be
read at all. One awk pass replaces the loop where it is safe to. - The candidate filter became a copy. With nothing already suspended, every blockable package
is a candidate — the per-package shell pass (2s quiet, 5s under the activation's own fan) was
a filter that filtered nothing. It is a straight redirect now. - The record writes in one pass (was 10s of 187 individual file appends through SELinux and
f2fs). - The after-read is built from what pm confirmed. The suspensions that pm answered yes to are
journalled as suspended, whatever the disk's flush lag says — the false no visible change is
gone, and with it the 7s second read. - The force-stop fan widened to twelve. The work per package is one binder call to AMS, which
keeps far more threads than twelve: 5s → ~3s in the field.
The settings-shaped knobs (aod, timeout, animations, haptics, rotate lock, blur, statusbar, scan,
location, sync, battery saver — and now double-tap-to-wake with its proc nodes) write in a parallel
fan that logs every write the phone confirmed, and their after-read is synthesised from that
log instead of a second full sweep. The synthesis is deliberately paranoid: one FAILED line, one
missing target, an empty log — any of them refuses it and the knob falls back to the real read.
A journal entry is a claim about the phone; the claims now come from confirmations.
Turning OFF: 47s → 21s
- The 187-package release loop is a twelve-wide fan of
pm unstop(was sequential: 14s → 4s). - The caps go off first, so the rest of the exit runs at full speed (4s invested, everything
after it faster). - Everything reverts side by side, and the exit ends where it always did:
verifycomparing the
phone against the journal —checked=27 drift=0 left-alone=0across three measured cycles,
including one that had slept (the deep knobs journalled and reverted too).
Sleeping: the freeze switches land last
The deep phase ran all six knobs at once — including deep_doze's force-idle and Data Saver's
restrict-background, which freeze the very system the other four knobs were still writing to.
Axion SPSM v3.8.2 — the keep-alive round
Axion SPSM v3.8.2 (versionCode 73)
The keep-alive round: an app this mode stopped can start again, and you choose which ones never stop.
Your messages had gone quiet, and the log explains it
The morning after the first overnight measurement, the phone was checked with the mode off — and
173 packages were still force-stopped, WhatsApp and the mail client among them. Nothing on
screen said so. The mail client had simply stopped receiving anything.
The cause is a difference the code had treated as a detail:
| what the mode did | how it comes back |
|---|---|
pm suspend — freeze the app |
the phone wakes it on the next push. pm unsuspend is the undo, and every exit path called it |
am force-stop — stop the app |
nothing wakes it. Android does not start a stopped package for a push, an alarm or a broadcast. Only a person opening it clears the state |
The second half had no inverse. The module's own comment assumed an app "simply starts again when it
is next opened", which is true for a game and wrong for anything that has to receive messages.
Fixed: the force-stopped set is written down as it happens (state/stopped_by_us.tsv) and
released with pm unstop on the way out — on the ordinary exit, in six-restore, and outside the
guard on the suspend record, because the sweep stops packages that record never names. The launcher
is deliberately not in the record: home_swap stops it and starts the mode's own home straight
back, so it is stopped-and-running rather than left stopped.
Background apps — the section you asked for
The six slots already kept six apps alive. You asked for a place to say "these must keep running",
without a limit, and with calls and SMS never in question.
New screen: Background apps (the ✓ button on the home screen). Every installed app, tap to keep,
tap again to release. Kept apps are listed first and marked kept awake.
What being on that list means — it is honoured by all three of the things this mode does to an app:
- never suspended, so its pushes keep arriving;
- never force-stopped, so it is never left dead;
- never pushed to the restricted standby bucket, and its background-op is left alone.
Adding an app takes effect at once, not at the next screen-off: if the mode has that app frozen
or stopped right now, it is released there and then — you can watch it start working again.
Calls and SMS do not need to be listed and cannot be broken. They are protected by the phone's
own ROLES (dialer, SMS, emergency) — the same protection that has always been there — so they stay
reachable whatever the list holds. This screen is for the chat apps, the mail apps and everything
else whose messages must not go quiet.
The list is yours, not session state: it survives an exit, a reboot and a re-flash of the module.
Under the hood it is /data/adb/spsm/keep_awake.txt, and the same thing is available from a shell:
sh /data/adb/spsm/scripts/engine.sh keep list
sh /data/adb/spsm/scripts/engine.sh keep add com.whatsapp
sh /data/adb/spsm/scripts/engine.sh keep remove com.whatsapp
Measured, not assumed
- a kept app is never suspended, never force-stopped and never bucket-restricted, while an app not on
the list still is — asserted in the test suite; keep addon an app that is frozen and stopped releases both immediately — the unsuspend and
thepm unstopare asserted;- the list survives an exit, because it is a choice and not session state — asserted;
- the exit releases every app it stopped, and clears its own record so no later exit frees a stop
that was never ours — asserted.
Suite: 661 passed, 0 failed; codec 252 checks, 0 failed.
Install
- Magisk / KernelSU: flash
Axion-SPSM-v3.8.2-RMX3430.zipfrom this release. The same zip is committed in the tree atrelease/. - App only:
module/app/AxionSPSM.apkin the branch is the same build.
Check it landed
- The power-saving home screen shows a third button — Background apps (✓).
sh /data/adb/spsm/scripts/engine.sh keep listanswers.sh /data/adb/spsm/scripts/engine.sh versionsays v3.8.2.
v3.8.1 — the exit round: goodbye in seconds
Axion SPSM v3.8.1 (versionCode 72)
The exit round: leaving the mode costs seconds, not minutes. No feature changed.
The evidence
The brief arrived with the owner's own v3.8.0 field log. It shows:
- activation 56 s, of which the block apply spent 25 s idling 186
apps one fork at a time — apps it had just force-stopped — and the
mode-on sweep spent another 5 s force-stopping the identical set again; - exit ~117 s, of which
revert block_other_apps took 100s— the
post-revert verify re-reading every value of every knob a second time,
thirteen full snapshots at once, while the owner pressed home seven
times waiting; - two boot-time unfinished-session exits (17 s, 23 s) paying the same
re-read tax, plusWARN … want [0] got []false-drift lines that were
artefacts of that same re-read.
What changed — the installer's method
1. The verdict comes from the restore's own account. Every restore
already reads each value it touches — it has to, to know what is still ours
to undo — and now records what happened as it happens: kept (a newer
value, not ours anymore), failed (the write was refused, with the value's
name and both sides), wrote. knob_revert reads that account and is done:
no second full read of every knob on the way out.
The one-round read-back stays where silence can hide: a knob with three
or fewer single targets (navigation, brightness, the switches) still gets
its verification read, because a ROM that accepts a settings put and does
nothing reports no failure — only a read catches it. That is also why the
field log's want [0] got [] lines disappear: they were the removed
re-read misreading the world mid-exit.
2. A blocked app is stopped once per session. The block apply no longer
runs am make-uid-idle per app (suspension already implies idle to
ActivityManager) and marks the blocked set as handled, so the mode-on sweep
hunts only strays (am kill-all) instead of re-force-stopping 186 apps it
stopped seconds earlier. The apply fan widens from two knobs at a time to
three.
3. The user's own values, still sacred. A value changed since apply is
detected during the restore's own read and left alone — keep <knob>: a value was changed externally since we applied it — with the small-knob
read-back confirming it independently. The apply-time silent-refusal note
(applied, did not take, and was put back by the module) is unchanged.
Recovery is untouched: su -c sh /data/adb/spsm/scripts/engine.sh six-restore. engine.sh verify is untouched.
Harness
646 checks, 0 failed, including the new case 89: a 40-package block is
replayed and the sweep must not re-stop it; a big-record knob's revert must
end with no read beyond the restore; a user-changed value must survive the
exit; a refused write must still be named with both sides.
Install
Mode off → flash Axion-SPSM-v3.8.1-RMX3430.zip → reboot.
Download
Flashable zip (also committed in this repo at the tag):
https://raw.githubusercontent.com/Rocker14427c/AXION-BS/v3.8.1/release/Axion-SPSM-v3.8.1-RMX3430.zip
sha256: 69fad0c95e7ae0eeff5672dc15bb8309829ff770d4ad0b0d0f00a43c49a0ce08
Reference / fallback
v3.8.0 remains published as a fallback build: https://github.com/Rocker14427c/AXION-BS/releases/tag/v3.8.0
v3.8.0 — the architecture round: fewer questions, not a faster asker
Axion SPSM v3.8.0 (versionCode 71)
The architecture round: measured where the phone's time went, then took it out. No feature changed.
The method
Not a rewrite, and not "convert it to C++". The workload is mostly waiting on
Binder round-trips to system_server — the language of the waiter barely
matters; the number of round-trips and forks is everything. So the harness's
own instrument did the analysis: the test stub records every command the phone
receives. One activate+exit cycle with 40 blocked packages cost 449 phone
calls, and the daemon forked sleep once a second for as long as it lived.
What changed — three mechanisms
1. Package work, batched. pm accepts a whole list of packages in one
call. Blocking, releasing, recovery and the sweep now ask for forty apps
per call, with the proven per-app path as an automatic fallback if a phone
refuses a batch. Measured on the 40-package cycle:
| phone calls | v3.7.12 | v3.8.0 |
|---|---|---|
| pm suspend | 43 forks | 2 calls |
| pm unsuspend | 43 forks | 2 calls |
| make-uid-idle | 43 (told twice) | 43 (told once) |
| total | 449 | 367 |
On the real ~190-app phone: roughly 370 fewer forks per session cycle —
minutes of min-frequency-core CPU returned to the phone.
2. The forkless nap. The daemon's sleep forked a process every tick —
one per second while the phone is in use, ~86,400 forks a day. The nap is
now a read with a timeout on a pipe the daemon holds open at both ends: zero
forks, identically interruptible (the app's poke breaks the read exactly as
it killed the sleep), with the old behaviour kept as a fallback if the pipe
cannot be made.
3. The sweep stopped repeating itself. The block apply already hands every
app to ActivityManager as idle; the sweep's full pass re-told the identical
set seconds later — one fork per app for a fact already told. The memory
reclaim (force-stop) stays; the repeat is gone.
What did NOT change
Every option, default, scope and tag; the six slots and their immediacy; the
recovery command su -c sh /data/adb/spsm/scripts/engine.sh six-restore; the
journal and its restore guarantee; the boot heal; the launcher, plumbing and
overlay protections; the caps-last/caps-first order; the tile and the app.
The harness proves the equivalence: 637 checks, 0 failed, twice
consecutively — including the new case that replays a 40-package block and
counts the forks (≤4 where 43 stood), exercises the per-app fallback on a
phone that refuses batches, and pins the forkless nap with its fallback.
Why not C++
A native binary would have made each remaining call marginally cheaper
while the phone still pays for the call itself. The wins here were in call
count and fork count — architecture, not language — and shell keeps the
journal/restore semantics that six months of device logs have already
survived. The right tool for this round was fewer questions, not a faster
asker.
Install
Mode off → flash Axion-SPSM-v3.8.0-RMX3430.zip → reboot.
Harness
637 checks, 0 failed — twice consecutively.
Download
Flashable zip (also committed in this repo at the tag):
sha256: `4984cb71c85b85f597fbbf2a8a8d9c2f558ea40fffe824e61e26b2b86387e253`
Reference / fallback
The previous implementation is frozen forever as tag v3.7.12 and its release zip: https://github.com/Rocker14427c/AXION-BS/releases/tag/v3.7.12
v3.7.12 — the built-in nav truly built in; launchers sacred; the audit
Axion SPSM v3.7.12 (versionCode 70)
The built-in nav, truly built in; your launchers made sacred; the audit round.
"You removed the option and didn't add it by default" — you were right, and the log says why
Your v3.7.11 log shows the home coming up with navigation_mode=2 — gestures —
and no nav line at all. The built-in bar I shipped in v3.7.11 still consulted
its own saved preference before applying, and your config carried
knob.nav_buttons=0 left over from an older version. The option was gone; its
ghost was still deciding.
Fixed: the built-in follows the power-saving home switch, and nothing else.
Home on → bar on. Home off → your own navigation. No ghost values, ever.
Your launcher was being suspended — now it is sacred
The same log named com.android.launcher3 and com.community.oneroom in the
block list. While this mode's own home holds the HOME role, your real launchers
hold nothing — so the protection that looked at role holders saw only the
mode's home, and your launchers went into the block list every session.
That one bug was behind three things you felt:
- the drawer that never showed suspended apps properly,
WARN block_other_apps did not return: com.android.launcher3…on every exit,- every exit ending in "1 value(s) could not be restored — forcing the
safety valves".
Now anything that can answer the HOME category is protected — by role and by
the category query — so all your launchers, current or not, are never suspended
or restricted. Exits now end clean, no safety valves.
The exit's last wide-open fan, bounded
The exit's revert ran a dozen knobs side by side, each re-reading its own
values to prove the revert — your block_other_apps revert spent 103 seconds
losing that race against its siblings. It is bounded six at a time now, like
every other fan: seconds, not minutes, and the interface wins the CPU
throughout.
The audit
A full pass over module and app, removing everything dead — each removal
verified unused across scripts, app and tests before cutting:
- the Low-Power mode write path (
set_power_mode/release_power_mode)
— the option was removed in v3.7.5 at your direction; its writer stayed
behind. The read side stays: the governor still diagnoses with it. - two unused journal helpers, an unused recents-component reader, and two
dead recents wrappers the engine never called; - in the app: a toggle-state map that was written twice and never read.
Install
Mode off → flash Axion-SPSM-v3.7.12-RMX3430.zip → reboot.
Recovery (unchanged)
su -c sh /data/adb/spsm/scripts/engine.sh six-restore
Harness
623 checks, 0 failed — twice consecutively. New pins: a stale saved
nav_buttons=0 cannot silence the built-in; two seeded launchers are never
suspended; the exit ends clean with the safety valves holstered; the exit fan
is bounded.
Download
Flashable zip (also committed in this repo at the tag):
sha256: `dbde101405bc301411fd16ced9e91696f94de9170e570af032f02a39b963b436`
v3.7.11 — smooth on minimum cores; your caps tip; the tile blue at last
Axion SPSM v3.7.11 (versionCode 69)
The log's seven minutes, paid back — smoothness on minimum-speed cores, your tip on the caps, the tile blue at last.
What your v3.7.10 log said, and what each number got
1. The navigation bar, fixed where it actually breaks. Every fan worker
now runs at background priority (renice 19): on cores the governor
holds at minimum, your phone's own interface — the bar is SystemUI drawing —
always wins the race for the CPU. No more disappearing bar while the mode
works, and everything feels smoother in daily use, which was the point.
2. Turning on and off, fast again. Three changes, one of them yours:
- The asleep options run six at a time instead of two (your log: the
screen-off deep phase held the phone for seven minutes — app_restrict
175 s, rom_bg_off 243 s). - Your tip, implemented exactly: the processor and graphics caps are
applied last on the way in and lifted first on the way out. Your
log showed why that is right — under the governor, the 188-app release
alone took 100 s; uncapped it is a fraction of that. - The daemon no longer waits on the deep phase. It hands the work its
own process and keeps ticking: the core timer fires on schedule (it fired
17 minutes late in your log), and a wake is answered instantly — the wake
waits its turn behind a running deep phase instead of giving up.
3. The tile, blue at last — and the button fixed by the same bug. The
app was reading the mode's switch file from a path nothing writes
(/data/adb/spsm/active instead of state/active), so it always believed
the mode was off: the tile never went active/blue, and the button stayed
"Turn on". One wrong path, both symptoms. The tile also carries its icon now,
which is what the system tints when a tile is active.
4. Three-button navigation is built into "Power-saving home". One
switch, as you asked — the separate option is gone from the list. The bar
applies while the mode's home is up, and both come back on exit, exactly as
before.
5. Suspended apps visible in your drawer. With the mode's home off, your
launcher (Pulse) is refreshed once on activation, so blocked apps show as
suspended immediately instead of keeping full-colour icons.
Install
Mode off → flash Axion-SPSM-v3.7.11-RMX3430.zip → reboot.
Recovery (unchanged)
su -c sh /data/adb/spsm/scripts/engine.sh six-restore
Harness
615 checks, 0 failed — twice consecutively. New pins: the caps-last/caps-first
order, every worker reniced, the detached screen-off with the retrying wake,
navigation hidden from the list but ordered after the home, and the launcher
refresh on activation with the home off.
Download
Flashable zip (also committed in this repo at the tag):
sha256: `db2d0d1453069991d694603b1e03aaf7b57fcbbc6b45fe879d7c0b8ced18d4e4`
v3.7.10 — the second hunt: recovery fixed; the app's words polished
Axion SPSM v3.7.10 (versionCode 68)
The second bug hunt: the recovery command, the boot heal, and the app's words.
The first hunt (v3.7.9) opened the engine's sweep, the widening paths and the
icon. This round opens the surfaces that round did not touch: the recovery
command every document points at, the boot that heals a dead session, and the
app you actually hold.
The recovery command dragged — minutes, in the worst moment
su -c sh /data/adb/spsm/scripts/engine.sh six-restore — the command in
every "if something looks wrong" section — unsuspended the record one
package at a time. On this phone the record held 264 packages: minutes
of sequential pm calls at the exact moment the phone is already misbehaving.
The boot heal in service.sh (which runs the same command when a dead session
left apps suspended) sat on the same slow queue.
It now unsuspends six packages at a time, the same bounded shape every
other per-package loop uses — the record that took minutes now takes seconds.
Recovery could fight a running mode
It also took no lock and asked no questions:
- Run while a screen-off transition was mid-flight, it mutated the same
suspensions the transition was writing — the journal and the phone quietly
disagreed afterwards. - Run while the mode was on, it freed the mode's blocked apps without a
word; the mode's next transition then re-applied its choices, and the
person was left wondering what happened.
Now: it runs under the lock (a transition in flight is waited for, up to
twenty seconds; if the lock still cannot be had, recovery says busy instead
of lying), and when the mode is on it says so in the log — "its next
transition will re-apply its choices; switch the mode off to keep them
freed". Recovery always works; now it also tells the truth.
The options screen spoke in code
Toggling an option toasted its internal id — wifi_off enabled. It now
toasts the option's own name from the same list the scripts publish:
"Wi-Fi off enabled". One of those small things that decides whether a
screen feels finished.
Also checked this round, and clean
The Quick Settings tile (detached transitions, honest busy state, watchdog on
every read), the screen-state publisher (event-driven, no polling, instant
wake), the boot receiver (guarded, cannot break a boot), and the root command
layer (bounded waits everywhere) — all audited; no defects found.
Install
Mode off → flash Axion-SPSM-v3.7.10-RMX3430.zip → reboot.
Recovery (unchanged command, now fast)
su -c sh /data/adb/spsm/scripts/engine.sh six-restore
Harness
600 checks, 0 failed — including the new recovery case: bounded, under the
lock, answers with what it freed, honest while the mode is on, and the exit
after a recovery leaves the phone clean.
Download
Flashable zip (also committed in this repo at the tag):
https://raw.githubusercontent.com/Rocker14427c/AXION-BS/v3.7.10/release/Axion-SPSM-v3.7.10-RMX3430.zip
sha256: af3f58695f7000ac0733628a47dfeb4dd973192c325430cdcb0f79c8170741b0
v3.7.9 — the bug hunt; options rewritten plainly; the icon fixed
Axion SPSM v3.7.9 (versionCode 67)
The bug hunt: the sweep treadmill, the overlays, and an option list that reads like your phone's own.
The bug hunt — three finds, from your own v3.7.7 log
1. The memory sweep was running in circles. Your log shows
background sweep: 264 frozen app(s) stopped three times — once when the
mode started, again at every screen-off, again on Clear All. But a suspended
app cannot start, so it cannot take memory back: re-stopping the same 264
apps every time only kept your phone busy for 15 seconds a sweep, with the
load spike riding along. Now the full pass runs once per session; every
sweep after it reaps the strays and reports the memory — which is all the
phone actually needs.
2. An overlay was in your block list. Your log's list starts
android android.axion_auto_generated_rro_product__ android.ext.services….
That second name is an RRO — a runtime resource overlay: a package that is
only resources, with no code to stop, and one that apps use for their
theming. The system-app widening had suspended it because its name appeared
in pm list packages -s. Overlays are now skipped by name in both widening
paths (blocking and background limits) — they can never be touched again.
3. The exit log overstated its subject. It said "released the six-slot
record" while releasing every app the mode had suspended — 264 of them,
slots or not. It now says "released every suspended app", and the sweep's
light pass logs exactly what it did instead of implying it did nothing.
The option list, rewritten like an OEM's power-saving mode
You asked for every option's title and detail to read formally and plainly,
the way a phone maker's own premium power-saving mode reads. All 31 are
rewritten — same behaviour, same defaults, same positions; only the words
changed:
| was | now |
|---|---|
| Power-save governor, always | Processor power-save |
| Graphics at minimum, always | Graphics at minimum |
| Sleep cores 2 to 7 after a minute | Sleep six cores after a minute |
| Hand back background memory | Free background memory |
| 15-second screen timeout | Shorter screen timeout |
| Turn off Wi-Fi / Bluetooth / NFC / location | Wi-Fi off / Bluetooth off / NFC off / Location off |
| Stop background scanning | Background scanning off |
| Restrict the ROM's background work | Restrict the ROM's background services |
| Cap the frame rate (30 fps) | Frame rate capped at 30 fps |
| …and 22 more, same voice throughout |
Each option is still one switch with one short, honest sentence — including
the two promises you set in writing: the processor line still says no
frequency limit is ever written by hand, and the system-app line still says
Android's own essentials are never touched.
The icon, fixed
The battery filled the whole tile — 67% of the adaptive canvas, past the
66% safe zone launchers are drawn around — so it looked like a battery with
no icon around it. It is redrawn at 53% of the canvas on the same pure
black, and the legacy black square got proper margins too. Same art, same
colours; now it sits in the tile the way an icon should.
Install
Mode off → flash Axion-SPSM-v3.7.9-RMX3430.zip → reboot.
Recovery (unchanged)
su -c sh /data/adb/spsm/scripts/engine.sh six-restore
Harness
594 checks, 0 failed — including the light-sweep pins (the second sweep must
not re-stop one app, and a new session must sweep fully again), the overlay
case, and the renamed options pinned with their promises word for word.
Download
Flashable zip (also committed in this repo at the tag):
https://raw.githubusercontent.com/Rocker14427c/AXION-BS/v3.7.9/release/Axion-SPSM-v3.7.9-RMX3430.zip
sha256: 9179639ae62deb07752b2757e757459e24178b253245db189ac3401646e73bc4
v3.7.8 — the parallelism bounded; the phone's plumbing untouchable
Axion SPSM v3.7.8 (versionCode 66)
The load spike and the vanishing navigation bar, fixed at their source; the share resolver untouchable.
What you saw on v3.7.7, one by one
You reported four things: everything working too slow, applying and exiting
taking far longer than normal, Franco showing a high average load ("never
happening before"), and the three-button navigation bar disappearing
completely for 7–8 seconds, many times. All four were the same bug wearing
different clothes.
v3.7.7's parallelism had no ceiling. The per-package loops and the wake /
deep-phase fans ran every call at once — on the wake, on every screen-off and
on exit, dozens of pm and cmd subshells were asked of the phone in the
same instant, on cores the power-save governor holds at minimum frequency.
The run queue spiked (Franco's average load), every call in the crowd waited
for every other one (apply and exit slower than before), and SystemUI
starved — the navigation bar is SystemUI drawing, so 7–8 seconds without it
is 7–8 seconds of SystemUI not getting scheduled.
Fixed where it started — every fan now has a ceiling:
- Per-app work runs six packages at a time (apply, restore, the ROM
background option, "Block other apps" both ways, the background sweep). - The engine's phase fans run two options at a time (wake, deep apply,
deep release) — and the wake still restores your cores first, before
anything else starts. - Same work in the same wall time, a fraction of the peak load. That is the
whole fix: concurrency with a ceiling, not a stampede.
The "intent resolver isn't available" dialog
That one was new option "Restrict system apps too" (v3.7.7) reaching too far:
its widening path suspended com.android.intentresolver — the share
resolver every "Share" button in every app routes through — and Android
answered with its suspended-app dialog when you backed out of an app.
The resolver can never be suspended again. The resolver, the permission
controller, the document picker and the media provider now sit in the
never-touch set beside the dialer, SMS, emergency, keyboard, launcher and
modem — no option, now or later, suspends them.
- The option is safe to leave ON — that is what it is for on OEM phones.
- On a clean ROM like your AxionOS it is still fine to leave OFF.
Also
- The three doze-state reads carry timeout lids (15 s / 15 s / 5 s). Your
v3.7.5 log showeddumpsys deviceidleblocking for 889 s once; a read that
hangs can now cost seconds, never a quarter of an hour. - Nothing else changed: the cores, the six slots, the tile, the recovery
command and every option's behaviour are exactly as v3.7.7 shipped them.
Your two-minute test: what the log actually says
The log you sent has one screen-off long enough to check: the screen went off
at 11:14:21 and came back at 11:16:42 — 2 minutes 21 seconds. There is
no cores_sleep line anywhere in the log. This time the cores did not
sleep — and the reason is v3.7.7's own slowness eating your test:
- The module's daemon is a single loop. On screen-off it runs the whole deep
phase itself, and on v3.7.7 that phase took 2 minutes 21 seconds of
unbounded parallel calls fighting each other on minimum-frequency cores.
The daemon could not so much as look at the screen until 11:16:42 — the
same second you woke the phone. Its one-minute core timer never got a turn. - The proof is in the log itself: the daemon prints an
aliveheartbeat
every minute it is allowed to run. Across your screen-off there is not one
heartbeat between 11:14:21 and 11:17:28 — it was blocked the whole time.
So the timer starved for exactly as long as the deep phase. v3.7.8's
bounding is what gives the cores their minute back: the same phase, six
packages and two options at a time, finishes well inside a minute even with
264 apps to stop — and the timer fires on schedule. The feature itself is
proven on your phone: your v3.7.5 night log shows
cores_sleep: 6 core(s) asleep - cores 0 and 1 stay awake.
Check it on v3.7.8: mode ON → screen off → wait a minute or two →
su -c cat /sys/devices/system/cpu/cpu2/online
0 = asleep (cpu3–cpu7 will read the same; cpu0/cpu1 stay 1). Wake the
phone and every core is back before anything else runs.
Recovery (unchanged, and always in the docs)
su -c sh /data/adb/spsm/scripts/engine.sh six-restore
Install
Mode off → flash Axion-SPSM-v3.7.8-RMX3430.zip → reboot.
Harness
586 checks, 0 failed — including the new bounded-fan cases and a case that
widens the system-app set the way the option does and proves the resolver and
its plumbing are never suspended.
Download
Flashable zip (also committed in this repo at the tag):
sha256: `ac523791d3a868699960d0999087e575df1f225975d927ade45d29a610d8d024`