Files
plezy/android/app/proguard-rules.pro
T
edde746 da21481ff3 fix(android): keep the reflected media3 MatroskaExtractor fields under R8
AssMatroskaExtractor and MatroskaLatmSupport reflect MatroskaExtractor's private extractorOutput/subtitleSample fields by name, but no keep rule covered them: R8 renames the fields and every MKV direct-play in a release build fails constructing the extractor. Adds the keepclassmembernames rule (descriptors verified against media3 1.11.0 in the Gradle cache) and extends check_shrinker_rules.py to scan Kotlin/Java reflection across all android src/main roots including libass.
2026-08-21 19:23:40 +02:00

38 lines
2.3 KiB
Prolog

# Flutter turns minification on for every release build (FlutterPlugin sets
# releaseBuildType.isMinifyEnabled), and appends this file when it exists. Anything the
# app reaches only by name reflection or JNI therefore needs an explicit keep here.
# The bundled Media3 FFmpeg audio decoder (ALAC, DTS, DTS-HD, TrueHD, ...).
#
# DefaultRenderersFactory instantiates FfmpegAudioRenderer through Class.forName and no
# app code references it, so R8 shrinks the class away; media3's own consumer rules only
# -keepclassmembers its constructor, which neither keeps the class nor pins its name.
# ffmpeg_jni.cc separately resolves FfmpegAudioDecoder and its growOutputBuffer callback
# by name in JNI_OnLoad, and returns JNI_ERR when either is missing, which fails the whole
# System.loadLibrary("ffmpegJNI") call.
#
# Without these keeps a release build silently loses every codec this decoder adds:
# TrueHD/DTS-HD land on MediaCodecAudioRenderer, which has no decoder for them, and
# playback bails to the mpv fallback and loses ExoPlayer's Dolby Vision handling (#1703).
-keep class androidx.media3.decoder.ffmpeg.** { *; }
# growOutputBuffer's JNI descriptor names this type, so it may not be renamed either.
-keep class androidx.media3.decoder.SimpleDecoderOutputBuffer { *; }
# MatroskaExtractor.init is final and its ExtractorOutput / subtitle scratch buffer live
# in private fields, so the extractor wrappers reach both by name: AssMatroskaExtractor
# (android/libass/.../media/extractor/AssMatroskaExtractor.kt) resolves extractorOutput
# and subtitleSample with getDeclaredField to redirect ASS subtitle samples, and
# MatroskaLatmSupport (android/app/.../exoplayer/MatroskaLatmSupport.kt) resolves
# extractorOutput the same way to wrap LATM tracks.
#
# R8 renaming either field makes getDeclaredField throw; AssMatroskaExtractor resolves
# them in its companion object, so the throw surfaces as ExceptionInInitializerError
# while constructing the extractor every MKV direct-play, release builds only. Only
# the *names* need pinning: MatroskaExtractor uses both fields itself, so they survive
# shrinking through the compile-time subclass references.
-keepclassmembernames class androidx.media3.extractor.mkv.MatroskaExtractor {
private androidx.media3.extractor.ExtractorOutput extractorOutput;
private androidx.media3.common.util.ParsableByteArray subtitleSample;
}