vc=52: R8 enabled + surface-handoff polish

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.
This commit is contained in:
Kayos 2026-05-26 08:43:06 -07:00
parent dc1fff00db
commit ebe1fc8464
5 changed files with 115 additions and 3 deletions

View file

@ -799,6 +799,12 @@ private fun InlinePlayer(
PlayerView(ctx).apply {
player = controller
useController = true
// Same surface-handoff polish as the
// fullscreen PlayerView — hold the last
// frame on dispose so the inline ↔
// fullscreen transition doesn't flash
// black between detach + reattach.
setKeepContentOnPlayerReset(true)
}
},
update = { it.player = controller },

View file

@ -178,6 +178,14 @@ fun PlayerScreen(
PlayerView(ctx).apply {
player = controller
useController = true
// Keep the last frame on screen when this
// view's player is reset (fullscreen →
// inline transition). Without this, the
// detaching PlayerView flashes black for
// ~1 frame before the receiving view takes
// over the surface.
controllerHideOnTouch = true
setKeepContentOnPlayerReset(true)
}
},
update = { it.player = controller },