WorkManager periodic worker hits the repo's index-v2.json, parses
the highest versionCode for our package, compares with
BuildConfig.VERSION_CODE. When newer: posts a notification with
ACTION_VIEW on the APK URL — Android's DownloadManager picks it up
and the system installer takes over. No INSTALL_PACKAGES perm
needed.
Settings:
- Check for updates toggle (default on — closing NewPipe's silent
staleness gap is the explicit motivation)
- Interval picker (1h / 6h / 24h, default 6h — WorkManager has a
15-min periodic floor anyway)
- Last-checked timestamp + 'update available' tag when caught-up
state is dirty
- Check now button — runs the same path as the worker so behaviors
stay identical
Cold start fires one check too so users see pending updates without
waiting a full interval.
R8 keep-rule for UpdateCheckWorker added — WorkManager instantiates
workers by name via reflection.
R8 (minify + resource-shrink) flipped on for BOTH debug AND release
variants — we publish the debug APK to fdroid (per existing
pipeline), and the audit-flagged Log.d strip discipline required R8
to actually run on the variant we ship.
New strawApp/proguard-rules.pro covers:
* UniFFI bindings (uniffi.strawcore.*) — reflective FFI dispatch
from Rust side, must survive minification
* JNA — Library subclasses reflectively loaded by name
* kotlinx-serialization @Serializable — generated $$serializer
companions, kept via both the package-anchored rule and the
annotation-wildcard rule for belt + suspenders
* Media3 session Parcelables (cross-process via Binder)
* Compose runtime + Strawcore exception hierarchy
Surface-handoff polish on inline ↔ fullscreen transitions:
setKeepContentOnPlayerReset(true) on both PlayerViews (inline in
VideoDetail + fullscreen Player). When the detaching view's player
is nulled on dispose, it holds the last rendered frame instead of
flashing black. The receiving view's surface takeover then renders
the next frame without the ~1-frame black gap. Round-4 audit
HIGH-5 was the closest writeup.
Expected APK-size win from R8: ~30-40%. Need real-device
verification post-install — the keep rules are best-effort and a
missing rule manifests as runtime ClassNotFoundException or
silently-broken kotlinx-serialization decoding.