Files
amethyst/amethyst
Claude c2a021be53 fix: scope R8 keep rules so Play's DEX optimization checks pass
Play Console reports Optimization 13% / Obfuscation 0%, both under the 25%
threshold that restricts store visibility and publishing.

The cause was three blanket rules, present in both amethyst/proguard-rules.pro
and quartz/consumer-rules.pro (the latter merged into every consuming app's R8
config, this one included):

  -dontobfuscate
  -keepnames class ** { *; }
  -keep class com.vitorpamplona.{quartz,amethyst}.** { *; }

-dontobfuscate turns renaming off program-wide, and -keepnames is shorthand for
-keep,allowshrinking: it permits shrinking but neither renaming nor
optimization. Applied to `**` it disabled R8 for the whole program, third-party
libraries included — hence 0% and 13%.

Replaced with keeps scoped to what is actually reached by name at runtime:

  - ArtiLogCallback — libarti_android.so does GetMethodID("onLogLine") on it.
    (ArtiNative itself is already covered by the default `native <methods>`
    rule, which pins the class of a JNI symbol.)
  - Jackson's reflective data binding only: nip47WalletConnect.rpc.** and
    experimental.clink.**, plus the three on-disk JSON stores
    (ScheduledPost/ScheduledPostFile, PowJobsFile/PersistedPoWJob,
    ResourceUsageStore$UsageFile). Event, Filter, Message, Command, Rumor,
    EventTemplate, TagArray and the NIP-46/NIP-55 messages all go through
    hand-written StdSerializer/StdDeserializer pairs that use string literals,
    so they need no keep.
  - Enum constant FIELD names, kept blanket: the preference stores persist
    `enum.name` into DataStore and read it back with valueOf(), so renamed
    constants would reset every user's theme/font/Tor/connectivity setting on
    upgrade. Only the field names are pinned; the enum classes are still
    renamed and their methods still optimized.
  - AmethystCastOptionsProvider — AGP generates keeps from manifest component
    android:name attributes but not from <meta-data android:value>.
  - ListenableWorker subclasses — WorkManager stores the class name in its own
    database and instantiates it by name after an update.
  - androidx.appfunctions declarations (pre-stable library).

Dropped -keepparameternames and the LocalVariableTable/LocalVariableTypeTable/
MethodParameters attributes: debug metadata nothing reads
(jackson-module-kotlin takes parameter names from @kotlin.Metadata). Added
-renamesourcefileattribute so the retained SourceFile cannot be read back as
the original class name.

Also removed quartz/proguard-rules.pro, commons/proguard-rules.pro and
commonsUI/proguard-rules.pro: no build script references them, and each was a
stale copy of the blanket keeps being removed here.

Verified on the playRelease DEX (:amethyst:minifyPlayReleaseWithR8 then
packagePlayRelease, both green, no R8 warnings):

  24,994 classes  -> 96.0% renamed (996 kept)
  102,555 field refs -> 86.3% renamed
  org.webrtc's 376 kept classes come from stream-webrtc-android's own consumer
  rules, not from us.

Every one of the 41 kept first-party classes is accounted for: manifest
components, the two Arti JNI types, the JSON file DTOs and the Cast provider.
Enum constants (PENDING, SYSTEM, PURPLE, ALWAYS, ...) confirmed present in the
DEX field table.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEoxktEZyTrAS33vVZBiwm
2026-09-18 20:45:21 +00:00
..
2024-06-24 14:13:55 -04:00