mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-12 03:21:08 +00:00
A user's first Steam setup never finished on an Honor Pad (Snapdragon 6 Gen 1, metered Wi-Fi with a 14 Mbit/s link). Their log stops at `downloading Steam: bins_linuxarm64_linuxarm64 (2/17)`. The log was shared 31 s into the session, so nothing had failed yet. The way the download works explains why it never got further. ## Why - **The session pauses the download.** With the default background behavior (Manual), a session pauses as soon as DroidDeck is hidden or the screen turns off. In the user's log that happened one second after start, before the download had begun. - "Keep downloads running" doesn't help. It's off by default, and it only recognizes Steam's own game downloads, not the runtime fetching the client. - A first run shows nothing for minutes, so leaving the app or letting the screen time out is exactly what people do. - **The download is bigger than the screen says.** The client is about 360 MB in 17 parts, and part 2 alone is 110 MB. The loading screen said "~1-2 min" and counted parts, not bytes, so on a slow link it looks frozen at about 5%. - **Nothing handles a bad connection.** Each part was a plain `curl -fsSL` with no timeout, no retry and no progress output. - A stalled connection could wait forever. - A failed one ended the session and threw away everything fetched, so the next try started from part 1. ## What changes - **`droiddeck-steam-install`**: - Parts go to `package/droiddeck-download` and stay there until the client is installed. - Each part resumes from the bytes on disk (`curl -C -`). - A transfer under 4 KB/s for a minute is dropped and resumed. - Attempts that make no progress back off 5–30 s, then give up with a clear error. Whatever arrived is kept. - A finished part is marked unpacked, so a later session skips it. - Bytes that fail their checksum are fetched whole again. A server that won't resume starts the part over. Parts left over from another client version are dropped. - A repair redoes every part once, and keeps what an interrupted repair already redid. - Every 5 s the step line also carries megabytes overall: `… (2/17), 45 of 360 MB`. - **Loading screen** (`LoadingState`): shows `Downloading the Steam client · 45 / 360 MB`, with the bar following the bytes. Older runtimes still show the part name. - **`SessionService`**: until the session's first frame, the download watch also checks whether the client is still to be fetched (no install stamp or client binary, or a repair requested). While it is: - the session stays awake with its wake and Wi-Fi locks, whatever the downloads setting says; - the notification shows "Steam download active" with **Suspend now**; - a `steam.client_download` event marks start and end. - The watch is set up before the first suspend decision, so a session started with the screen off isn't paused first. Once the client is there, the chosen behavior applies again. - **`droiddeck-session`**: the step no longer promises 1–2 minutes. ## Testing - `python3 -m unittest discover -s tools/tests -p 'test_*.py'`: 497 OK, 1 skipped. - `test_steam_install.py` gets a fake curl that drops connections, refuses to resume or fails on cue. - New cases cover: megabyte progress; resuming after a dropped connection; keeping finished and partial parts across a failed session; restarting a part the server won't resume; re-fetching bad bytes; dropping another version's parts; a repair resumed once. - Kotlin: `:app:testDebugUnitTest --tests 'com.droiddeck.launcher.session.*'` passes. That includes the new `LoadingStateTest` and the `clientInstallPending` cases in `SteamDownloadMonitorTest`. - RedMagic NP06J, with Background behavior set to Manual and "Keep downloads running" off (the user's settings), and a client repair requested: - Started Steam and sent DroidDeck to the background straight away. The client download stayed active for 30 s with no pause, and all 360 MB arrived. Then the session paused as Manual should. - Stopped a second repair during part 2. Part 1 was marked unpacked, the 110 MB part 2 was kept, and the repair marker stayed. - Started again: it resumed at 110 of 360 MB, unpacked part 2 without fetching it again, finished, and Steam started normally. - The loading screen showed `Downloading the Steam client · 248 / 360 MB`. Retested 2026-10-23 on the REDMAGIC tablet after merging main, which brought in the stable-channel fallback. Background behavior was set to Manual with "Keep downloads running" off. A client repair was forced, then Home was pressed right after Start: | Build | Session while hidden | Client download | |---|---|---| | main | suspended 1 s after Home | stuck at part 3/17 after 90 s | | this PR | kept awake until the client was in | all 17 parts, 362 MB in 46 s with MB progress; suspended once done | `tools.tests.test_steam_install` (22), `SteamDownloadMonitorTest` and `LoadingStateTest` pass. ## Not changed - **The download is the plain zips.** Valve's manifest also lists `.vz` (LZMA) versions, 228 MB instead of 360 MB. Using them needs a VZ decoder in the guest; that could be a follow-up. - **The stall and retry path** is covered by the tests but wasn't forced on the device.