# The app-wide R8 rules for a SoulStream release APK — the ones that belong
# to no single plugin.
#
# This file lives in the repo on purpose. The Gradle project that consumes it,
# src-tauri/gen/android/app, is GENERATED and gitignored, and
# `tauri android init` rewrites it, so a rule written into that project's own
# proguard-rules.pro is a rule with a short life.
# `bash src-tauri/android/build.sh --release` copies this file next to that
# project's build.gradle.kts, whose release build type reads
#
#     proguardFiles(*fileTree(".") { include("**/*.pro") }
#         .plus(getDefaultProguardFile("proguard-android-optimize.txt")) ...)
#
# — anything ending in .pro in that directory. Copying it is a no-op for the
# debug build: the debug build type sets isMinifyEnabled = false and names no
# proguard files at all, so the path the deploy pipeline runs every twenty
# minutes never reads a line of this.
#
# NOR are the rules for the wry/JNI bridge here. wry's build script writes
# proguard-wry.pro next to the Kotlin it generates, in
# app/src/main/java/com/soulstream/app/generated/, and the release build type's
# **/*.pro glob is recursive, so it is already picked up: Rust's native
# methods, WryActivity, Ipc's @JavascriptInterface, RustWebView.evalScript.
# proguard-tauri.pro, beside this file, keeps TauriActivity.getPluginManager().
# Duplicating either here would be a second place to get them wrong.
#
# Per-plugin rules are NOT here. Each plugin carries its own
# consumer-rules.pro inside crates/tauri-plugin-*/android, so they travel with
# the plugin into a regenerated gen/android and into a plain
# `npx tauri android build` too.
#
# NOTHING BELOW HAS BEEN PROVEN BY A BUILD. Every APK this project has ever
# made is assembleArm64Debug with minification off. See ANDROID.md →
# "The release build".


# Tauri reads its own annotations off the class files at RUNTIME:
# PluginHandle.indexMethods() asks each Method whether @Command,
# @ActivityCallback and @PermissionCallback are present, and all three are
# @Retention(AnnotationRetention.RUNTIME). proguard-android-optimize.txt is
# expected to keep them with `-keepattributes *Annotation*`, but that file is
# extracted from the Android Gradle plugin when a release build runs and no
# release build has ever run here, so it has never existed in this tree to
# read. Say it outright rather than inherit it from a file this project does
# not own and cannot see. Signature, InnerClasses
# and EnclosingMethod are for Jackson, which resolves an @InvokeArg field's
# declared type before it fills it.
-keepattributes RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,AnnotationDefault,Signature,InnerClasses,EnclosingMethod


# THE GAP. Tauri's own consumer rule is
#
#     -keep @app.tauri.annotation.TauriPlugin public class * {
#       @app.tauri.annotation.Command public <methods>; ... }
#
# and a class-member specification matches the members a matched class
# DECLARES. These four @Command methods are declared on app.tauri.plugin.Plugin
# — the abstract base every plugin extends — which carries no @TauriPlugin of
# its own; tauri's other rule for that package keeps only @JniMethod and
# native members. So no rule in the build names them, while
# PluginHandle.indexMethods() walks the superclass chain with
# getDeclaredMethods() and registers them by name regardless.
#
# registerListener is the one this app rides on. addPluginListener() in
# src/mobile/media.svelte.js and src/mobile/xfernote.svelte.js invokes
# plugin:media-session|registerListener and
# plugin:transfer-notice|registerListener, and those subscriptions are how the
# lock-screen card's prev/play/next/stop and the download notice's cancel and
# open get back into the app. Lose them and everything still looks right and
# nothing either of those buttons does works.
#
# Written as a precaution, not as a diagnosed bug: whether R8 reaches
# inherited members through tauri's rule could not be settled from source, and
# it cannot be settled on this machine at all. Six lines to stop asking.
-keep class app.tauri.plugin.Plugin {
    public void registerListener(app.tauri.plugin.Invoke);
    public void removeListener(app.tauri.plugin.Invoke);
    public void checkPermissions(app.tauri.plugin.Invoke);
    public void requestPermissions(app.tauri.plugin.Invoke);
}


# jackson-databind 2.15.3 — tauri's own dependency, the thing that fills every
# @InvokeArg — ships no META-INF/proguard rules of its own, and its
# databind/ext/Java7SupportImpl references java.beans.ConstructorProperties and
# java.beans.Transient, neither of which exists on Android. R8 in AGP 7+ turns
# a missing class into a BUILD ERROR, so without these two lines the release
# build may not get as far as producing an APK.
#
# If R8 names others, its own list is the answer: add what
# app/build/outputs/mapping/arm64Release/missing_rules.txt says to this file
# and run again. (jackson-core 2.15.3 scanned clean, and the
# java.lang.reflect.RecordComponent in jdk14/JDK14Util is a reflective string
# rather than a class reference, so it should not be reported.)
-dontwarn java.beans.ConstructorProperties
-dontwarn java.beans.Transient
