# R8 rules for the release build. # # 🔴 **This file did not exist, and `build.gradle.kts` referenced it anyway.** # R8 accepts a missing `proguardFiles` entry in silence, so the release build # ran with the platform defaults alone and nobody was told. What that cost: # answering a call on a release build killed the process instantly — # # Fatal signal 6 (SIGABRT), thread DefaultDispatch # JNI_OnLoad <- libjingle_peerconnection_so.so # System.loadLibrary # org.webrtc.PeerConnectionFactory # # — because WebRTC's native `JNI_OnLoad` resolves its Java classes **by name**, # and R8 had renamed them. The lookup fails and the library aborts the process # rather than throwing, so there is no Kotlin stack trace and nothing in the # call log: the app is gone before it can write one. Reported as "calling from # iOS to Android crashes Android when I hit answer" and, from the other side, # "iOS shows 2 calls, Android shows 0". One cause, two symptoms. # # ⚠️ **Debug builds cannot catch this and never will.** `connectedDebugAndroidTest` # runs the unminified variant, where every one of these classes still has its # real name. Every call test this project has ever run was blind to it. A # release-build call test is the only thing that would have. # --- WebRTC ---------------------------------------------------------------- # Everything, members included: the native side looks up classes, methods AND # fields by their source names. Narrowing this to class names alone is the # tempting half-fix and it still aborts, in a different frame. -keep class org.webrtc.** { *; } -dontwarn org.webrtc.** # Any class holding native methods must keep those names, or the JNI binding # that pairs them by signature finds nothing. -keepclasseswithmembernames class * { native ; } # WebRTC marks its JNI entry points with this annotation. Keeping the # annotation itself is what lets the rule above stay meaningful after R8's # attribute stripping. -keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod # --- Conscrypt ------------------------------------------------------------- # ⚠️ The engine selects Conscrypt explicitly by provider name (see # android/PARITY.md). Renaming its classes turns that selection into a silent # fallback to the JVM's own provider, which is a different implementation with # different behaviour — the exact class of divergence the parity tests exist # to catch, arriving only in release. -keep class org.conscrypt.** { *; } -dontwarn org.conscrypt.**