Repository navigation
Launcher: persist wallpaper and overlay to internal storage to eliminate boot timing race - #3317
Jesencloud wants to merge 5 commits into
Conversation
Jesencloud
commented
Nov 5, 2026
|
maintainer-bot review · this one needs a maintainer decision · Leans: merge (60%) Thank you for tracking down the cold-boot storage race and for the syncFile tests. This reads as a tested bug fix in the same spirit as #614 and looks mergeable. One thing worth confirming: removing a theme should still clear the internal copy once /sdcard is mounted. Why it goes to a maintainer: confidence 0.60 is below 0.75. Re-checked at this commit: the PR's own changes are the same as at the last review. Checks
This is a suggestion; a maintainer makes the final call. A maintainer can comment Reviewed by maintainer-bot · runs on 0G Private Computer |
|
A separate cache-write failure at With the actual helper and controlled stream failures over real temporary files, a read failure after the first 8-KiB chunk replaced the previous cache with those partial bytes. A first-copy failure also published a partial cache; an injected write failure similarly overwrote the previous bytes. These are synthetic host I/O tests, not observed Android storage failures or JPEG-rendering tests. A focused option is to write beside the destination, close successfully, then replace it; on read/write/rename failure, retain the previous cache and clean the staging file best-effort. Serialize calls if using one fixed staging filename. The existing length/timestamp skip can stay. A one-file local prototype changes 3/8 failing cases to 8/8 passing, plus a new rename-failure control (9 passing total). The isolated helper also type-checks against Android API 34 stubs. Costs: one extra image-sized temporary file during a copy and in-process serialization; this does not move the existing synchronous |
|
@SaviorOneZero |
|
The staged copy at A small correction is to delete the staging file and With the actual helper, real temporary files and controlled close failures, three added cases fail on this head: output-close failure with an existing cache, output-close failure on the first copy, and input-close failure. The correction passes 12/12 cases including the nine earlier controls; the four unchanged author helper tests also pass. The isolated corrected helper type-checks against Android API 34. These tests demonstrate publication despite a reported close failure; they do not demonstrate Android file corruption, a power-loss guarantee, a full launcher build or a physical-TV failure. No extra I/O or background work is added. |
|
@SaviorOneZero , Thanks for the precise catch on the try-with-resources |
|
@Jesencloud thanks, the staged, atomic syncFile with its tests is a really careful answer to the slow /sdcard mount. One change before merge: only run the onResume recheck when Config.load saw storage unmounted, using a flag cleared once it is mounted. That way TVs without a wallpaper never reload config or risk a recreate loop. Please also trim the description to what the diff does. We'll check back in 7 days. |
|
4a43dab to
5c3a8dd
Compare
|
The one-shot gate at A focused condition is With the verbatim mount branch in a host wrapper and controlled Config/Environment values, folder-only, JSON-only and wallpaper-disabled overlay cases fail on this head; that condition passes 7/7, including static wallpaper, no-theme, still-unmounted, initially-mounted and repeated-resume controls. The four author tests also pass with the actual extracted |
|
One older cache path at A focused option is to stage the serialized JSON beside the copy under the existing The actual These are isolated host I/O tests, not an observed Android storage failure, cold-boot test or full launcher build. Cost: one extra JSON-sized temporary file (the reader caps input at 64 KiB) and a rename during the existing load; no new timer, worker or dependency. No cross-process or power-loss guarantee is claimed. |
|
A separate choice-protection edge at Small correction: return a distinct failure result ( Using the actual three helpers, real files/FileInputStream and controlled input failures/chunked reads, 9 of 16 host cases fail on this head. The correction passes 16/16, covering unchanged-marker failures, retry, a real changed token, first acknowledgement, and missing/empty/oversized controls. Preferences are transactional Map stand-ins; this does not reproduce Android storage or SharedPreferences persistence failure. The uninstrumented corrected helpers type-check against API 34. No new buffer, timer, worker or normal-path file read is added; only short reads need another bounded read. A genuinely changed theme retains the current on-TV choices until its marker can be read and acknowledged. This is distinct from #844's signature-commit/crash-history issue and from the JSON-copy and resume-gate findings above. |
5c3a8dd to
83f3dbc
Compare
|
Thanks @SaviorOneZero for the thorough review and the three precise findings. All three are addressed in 1. Resume gate condition — the 2. Atomic overlay cache — 3. revisionToken I/O guard — All existing |
|
@Jesencloud thank you, the one-shot recheck behind storageUnmounted and the staged writes are exactly what we asked for. Since this changes what the launcher reads and copies at cold boot, it gets one real-TV cold-boot run (wallpaper and theme on the card, then a reboot) before it merges. No change is needed from you. |
|
Reproduced on another set, in case it helps with testing: Xiaomi MiTV-MOEU0 (ladybird), Google TV 14 (SDK 34), firmware After each cold reboot (two tries) Home comes up with the theme's layout (5-column dock, icon-only buttons), so the overlay came from the internal copy, but with no wallpaper: plain black. Pressing Home again does not change it. Reading |
|
Thanks @littlesteve01 for reproducing and confirming this on Xiaomi / Google TV 14! That exact cold-boot black screen behavior (layout loads from cache, but wallpaper fails because This PR addresses that by:
If you have a chance to build and test this branch ( |
…ate boot timing race
…t I/O edges Address three review findings from SaviorOneZero: 1. onResume recovery gate: also recreate for folder-only wallpaper collections (check.wallpapers) and JSON-only overlays (check.overlayApplied), not only a single static wallpaper. 2. readOverlay atomic cache: write the internal config.json copy through a .tmp staging file under SYNC_LOCK, matching the wallpaper syncFile pattern. A partial write no longer destroys the previous good fallback. 3. revisionToken I/O guard: return null on read exception or short read instead of "absent", so syncThemeChoices skips that load rather than clearing saved user choices. Read in a loop to handle partial reads. Missing, empty and oversized markers still return "absent" as before.
34b2011 to
935b8d2
Compare