Repository navigation
Linthra v0.2.9
Linthra v0.2.9
Linthra 0.2.9 is a stability and reliability release focused on making everyday playback, downloads, syncing, local libraries, Android, and Linux more predictable under failures, races, account changes, and disappearing resources.
There is deliberately no headline feature in this release. The work since 0.2.8 concentrated on making existing features hold up when operations overlap or something goes wrong.
Highlights
Playback is harder to knock off course
Playback now handles a much wider set of awkward timing and failure cases without getting stuck, showing the wrong state, or letting an older track leak into the one you selected.
Among the fixes:
- Play after Stop reloads the current track instead of reviving an older source or hanging on Loading.
- Pause, seek, Next, queue changes, session restore, repeat-one, and audio-focus changes keep the latest listener action authoritative while a track is loading.
- A failed or stalled remote stream has bounded recovery instead of silently remaining in a playing/loading state forever.
- Missing local files are reported as local-file problems rather than network failures.
- A failed track cannot silently replace the title/state of the track that is actually playing.
- Finished queues, restored queues, repeat-one loops, and replaying a recently played song behave consistently.
- Automatic skipping remains bounded and visible rather than silently running through the queue.
Downloads and smart pre-cache
Downloads and automatic caching now agree more reliably about ownership, cancellation, network policy, and account identity.
- Cancelling a download stays cancelled even when smart pre-cache overlaps it.
- A server error page cannot be saved as if it were an audio download.
- Downloads held for Wi-Fi start once the network policy allows them, including on Linux.
- A pre-cached copy promoted to a real download is not immediately treated as the oldest cache entry.
- Work started under an account or server that has since been replaced is not committed to the new session.
- Cached stream URLs are not reused after the account that authorized them signs out.
Syncing, playlists, favorites, and accounts
A large part of the hardening pass targeted operations that finish in a different order from the one they started in.
- Playlist and favorite edits made while a refresh is running are preserved.
- Older network answers cannot overwrite newer server/account state.
- Playlist pushes, refreshes, sign-outs, and server switches are reconciled without silently undoing the latest local action.
- Playback reporting stays with the account that started the play instead of moving to whoever signs in later.
- Jellyfin remote control follows the active session and remains available through normal loading/rebuffering transitions without leaving stale connections behind.
Local libraries and storage failures
Local-library operations now preserve the last known-good catalog more aggressively when storage is slow, unavailable, moved, or cannot be written.
- An unfinished or malformed media file cannot freeze a scan indefinitely in the cases covered by the new guards.
- Removing, changing, or reselecting folders is serialized against background refreshes so an overlapping scan cannot silently undo the choice.
- Picking an unreadable replacement folder leaves the existing library intact.
- Disk-full/read-only failures keep the previous catalog on screen instead of replacing it with an unrelated folder error.
- Local artwork can be recovered after the artwork cache is cleared.
- Supported move cases preserve song history such as favorites, play counts, and added dates.
- A rescan keeps an already loaded library visible while the replacement catalog is prepared.
Android and Android Auto
- Android Auto queue and library selections are tied to the item the listener actually picked, even when the underlying list changes or an earlier lookup finishes later.
- Back navigation closes selection/menu surfaces consistently instead of unexpectedly leaving the app.
- Media-session and remote-control actions follow the same playback intent as the in-app controls through loading and stalls.
Linux desktop
- Stream loss and failed opens are detected instead of leaving the UI playing or loading forever.
- Repeat-one state, pause/resume, and end-of-track handling are more reliable with the libmpv backend.
- Background window closing and graceful shutdown are more predictable.
- Network-status handling no longer leaves Wi-Fi-held downloads permanently queued when the desktop portal is slow or initially silent.
F-Droid reproducibility
F-Droid's rebuild of v0.2.8 exposed a reproducibility problem in the native FLAC fallback introduced in that release. The compiled code matched, but the GNU build ID in libflacJNI.so depended on build-machine paths that were present before AGP stripped the library.
0.2.9 links that FLAC JNI target without a GNU build ID and checks the built APK for all three Android ABIs. The same check also keeps the native hardening requirements in place: RELRO, BIND_NOW, 16 KB LOAD alignment, a non-executable stack, JNI-only exports, and stack-protector use.
This fixes the demonstrated v0.2.8 mismatch. Issue #703 should remain open until F-Droid performs its real rebuild of 0.2.9 and reports the per-ABI packages as successfully verified.
Privacy and security
This release does not restore casting. The receiver-trust work tracked in #575 remains contained.
Several fixes make account/server transitions safer: in-flight downloads, pre-cache work, playback reports, reachability results, and Jellyfin remote-control connections are prevented from being applied to a replacement session when their original session is gone.
Known limitations
The hardening work intentionally did not turn uncertain edge cases into speculative fixes. Known follow-ups include some vendored audio-engine lifecycle behavior, hard/unresponsive network-mounted local folders, and a few libmpv edge cases around device loss or unusual truncation. These remain follow-up work rather than being hidden behind broad claims in this release.
Casting also remains unavailable while #575 is unresolved.
Android and F-Droid
Canonical Android version for this release:
- versionName:
0.2.9 - base versionCode:
209999
Expected F-Droid split-ABI version codes:
- armeabi-v7a:
2099991 - arm64-v8a:
2099992 - x86_64:
2099993
F-Droid builds Linthra from source at the release tag and signs with its own key. GitHub APKs and F-Droid packages use different signing keys, so users should continue updating from the same distribution source they originally installed from.
Upgrade notes
No manual migration is expected. Libraries, downloads, queue state, server sessions, and settings remain in place across the update.
Thanks
Thanks to everyone reporting real-world failures and testing the fixes. 0.2.9 is intentionally about reliability: fewer surprising state changes, safer recovery when something disappears underneath the app, and clearer behavior when a request cannot be completed.