Bundling the background-refresh worker (originally planned as vc=60) into the same release as cache controls — they're both storage-and-refresh user-facing knobs, ships cleaner together. - StrawApp.onCreate calls FeedRefreshScheduler.applyFromSettings - R8 keep rule for FeedRefreshWorker (same reason as UpdateCheckWorker — WorkManager instantiates via reflection) - Settings UI: 'Auto-refresh subs' toggle (default off) + interval chip-row (30min / 1h / 6h) shown when enabled. Lives in the existing Local cache section since it's the same storage-and-refresh theme. Worker calls uniffi.strawcore.subscriptionFeed which fans out 50 parallel RSS fetches in Rust — 50 subs refreshes in ~1-2s in the background. Writes per-channel into FeedCacheStore so next cold open of Subs paints instantly.
90 lines
4.1 KiB
Prolog
90 lines
4.1 KiB
Prolog
# SPDX-FileCopyrightText: 2026 Sulkta-Coop
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
#
|
|
# R8 keep rules for the Straw app module. The legacy `app/proguard-rules.pro`
|
|
# is for the upstream NewPipe module — different namespaces, different
|
|
# rules. This file is OURS.
|
|
#
|
|
# AGP's getDefaultProguardFile("proguard-android-optimize.txt") handles
|
|
# the Android framework + AndroidX + Compose runtime defaults via
|
|
# consumer rules shipped with each library. We only need to spell out
|
|
# what those defaults can't see:
|
|
#
|
|
# * UniFFI bindings — reflective FFI dispatch from generated code.
|
|
# * JNA — reflects on every class extending com.sun.jna.Library
|
|
# (that's how the loadLibrary glue works).
|
|
# * Our kotlinx-serialization @Serializable types — their generated
|
|
# $$serializer companions get tree-shaken without explicit keeps.
|
|
# * Media3 session metadata Parcelables.
|
|
|
|
# -- UniFFI -------------------------------------------------------------
|
|
# Generated bindings live under uniffi.strawcore.*. The Rust side calls
|
|
# them via JNI symbol name; if R8 renames the class or methods, every
|
|
# extractor call NPEs.
|
|
-keep class uniffi.strawcore.** { *; }
|
|
-keep class uniffi.** { *; }
|
|
|
|
# -- JNA ---------------------------------------------------------------
|
|
# JNA looks up Library subclasses by Class.forName + reflection at
|
|
# load time. Anything that extends Library or has @FieldOrder must
|
|
# survive.
|
|
-keep class * extends com.sun.jna.Library { *; }
|
|
-keep class com.sun.jna.** { *; }
|
|
-dontwarn com.sun.jna.**
|
|
|
|
# -- kotlinx-serialization ---------------------------------------------
|
|
# Every @Serializable type gets a synthetic Companion + $$serializer
|
|
# class. R8 will strip the $$serializer if nothing visibly calls it
|
|
# (the lookup goes through reflection on the Companion).
|
|
-keepattributes *Annotation*, InnerClasses
|
|
-dontwarn kotlinx.serialization.**
|
|
|
|
-keep,includedescriptorclasses class com.sulkta.straw.**$$serializer { *; }
|
|
-keepclassmembers class com.sulkta.straw.** {
|
|
*** Companion;
|
|
}
|
|
-keepclasseswithmembers class com.sulkta.straw.** {
|
|
kotlinx.serialization.KSerializer serializer(...);
|
|
}
|
|
|
|
# Same dance for our top-level @Serializable types defined outside
|
|
# `com.sulkta.straw.**` (Rust DTOs, etc.). Belt + suspenders.
|
|
-keepclassmembers @kotlinx.serialization.Serializable class * {
|
|
static **$Companion Companion;
|
|
public static <1>$Companion Companion;
|
|
}
|
|
-keepclasseswithmembers @kotlinx.serialization.Serializable class * {
|
|
kotlinx.serialization.KSerializer serializer(...);
|
|
}
|
|
-keep class **$$serializer { *; }
|
|
|
|
# -- Media3 / ExoPlayer ------------------------------------------------
|
|
# Most of Media3 ships consumer rules but session-related Parcelables
|
|
# are reflectively reconstructed across process boundaries (the
|
|
# MediaController talks to PlaybackService via Binder). Keep their
|
|
# field names.
|
|
-keep class androidx.media3.session.** { *; }
|
|
-keep class androidx.media3.common.MediaItem { *; }
|
|
-keep class androidx.media3.common.MediaItem$* { *; }
|
|
-keep class androidx.media3.common.MediaMetadata { *; }
|
|
|
|
# -- Strawcore exceptions / DTOs reflected by UniFFI --------------------
|
|
# StrawcoreError is a sealed Throwable hierarchy exposed via UniFFI.
|
|
# Keep all subclasses + their fields so the Kotlin pattern-match works
|
|
# after minification.
|
|
-keep class com.sulkta.straw.feature.player.** { *; }
|
|
|
|
# -- Reflection-via-Class.forName paths from Compose --------------------
|
|
# Compose's runtime does some Class.forName for its own bootstrap; the
|
|
# AGP consumer rules cover this, but documenting the dependency here
|
|
# so a future bump doesn't surprise us.
|
|
-keep class androidx.compose.runtime.** { *; }
|
|
|
|
# -- WorkManager Worker classes ----------------------------------------
|
|
# WorkManager instantiates Worker subclasses by class name via
|
|
# reflection (`Class.forName(workerSpec.workerClassName)`). If R8
|
|
# renames our UpdateCheckWorker the scheduler enqueues it but the
|
|
# instantiation fails silently and no checks ever run.
|
|
-keep class com.sulkta.straw.feature.update.UpdateCheckWorker { *; }
|
|
-keep class com.sulkta.straw.feature.feed.FeedRefreshWorker { *; }
|
|
-keep class * extends androidx.work.ListenableWorker { *; }
|