androidkotlinproguardandroid-r8

Why is R8 is not obfuscating certain classes?


Our app is using R8 to shrink and obfuscate and both work in general but some classes aren't obfuscated, when they should be. As an example I was looking specifically into one class that should be obfuscated: TokenStorage.

The Gradle configuration is:

debuggable = false
shrinkResources true
minifyEnabled true

// adding the Proguard files from a dedicated directory
file('proguard-rules').listFiles().each {
    proguardFile it
}

The class appears in the seeds.txt file (so it should NOT be removed):

com.package.storage.TokenStorage: TokenStorage(com.package.storage.StorageDelegate)

The class obviously does not appear in usage.txt but some of its private functions do:

com.package.storage.TokenStorage:
    private final com.package.api.model.Tokens getTokens()
    private final com.package.api.model.Tokens getTokensAndUpdateCache()

The mapping.txt file indicates that it won't be obfuscated but some of the properties are:

com.package.storage.TokenStorage -> com.package.storage.TokenStorage:
# {"id":"sourceFile","fileName":"TokenStorage.kt"}
    com.package.storage.StorageDelegate storage -> a
    kotlinx.coroutines.sync.Mutex lock -> b
    com.package.api.model.Tokens tokens -> c
    com.squareup.moshi.JsonAdapter moshiAdapter -> d
    ...

The configuration.txt file has no mention of that specific class. The class also doesn't extend anything and the fact that other similar classes are obfuscated tells me that we don't have an accidental keep everything public or some other catch-all keep config.

Our requirements:

I understand that we could add a -keep,allowobfuscation line but we can't add this for every single class. What we want is:

Is this possible and if yes how?

PS: Tested the code on https://playground.proguard.com/ and no indication that configuration.txt has keep rules for that specific class

PS2: the class doesn't extend other classes and the only dependency on a 3rd party lib is Moshi:

private val moshiAdapter = Moshi.Builder().build().adapter(Tokens::class.java)

That property and two others are obfuscated btw: enter image description here


Solution

  • I'd suggest you to find the rule that keeps the class first (-whyareyoukeeping directive can be handy for that), and check how exactly it is being configured.

    For the case where third-party dependency with too broad rules unnecessarily affects your classes, you might consider ignoring them with KeepRules#ignoreExternalDependencies (available in AGP 7.3, deprecated in AGP 8.4, see example usage here) or KeepRules#ignoreFrom (available in AGP 8.4), and then applying stricter rules by yourself. This effectively allows to "rewrite" dependency's proguard rules.