diff --git a/CHANGELOG.md b/CHANGELOG.md index 24267da..ecd92ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,12 +18,15 @@ [malware protection](https://uploadcare.com/docs/security/malware-protection/), and [background removal](https://uploadcare.com/docs/remove-bg/). - Fixed authorization signature for requests with url parameters. + - Added Proguard rule to keep DTO classes to avoid issues with network JSON deserialization. - Widget: - SocialApi doesn't use `GET /sources` method anymore. + - Added Proguard rule to keep DTO classes to avoid issues with network JSON deserialization. - Project: - Migrated Gradle builds from Groovy to Kotlin. - Example: - Removed sorting options by file size from `UploadFragment`. + - Enable R8 shrinking code for release build to enable Proguard's rules. ## 3.3.0 - Library: diff --git a/build.gradle.kts b/build.gradle.kts index cd475c1..4251bd4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,7 @@ buildscript { repositories { maven(url = "https://maven.google.com") + maven(url = "https://storage.googleapis.com/r8-releases/raw") google() mavenCentral() } @@ -12,6 +13,10 @@ buildscript { classpath("com.android.tools.build:gradle:${libs.versions.gradleVersion.get()}") classpath(libs.kotlin.plugin) classpath(libs.navigation.safe.args.plugin) + + // Required to support for sealed classes until AGP 8.2 + // https://issuetracker.google.com/issues/227160052#comment37 + classpath(libs.tools.r8) // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 7b8993d..9ab9adc 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -24,7 +24,7 @@ android { buildTypes { release { - isMinifyEnabled = false + isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 60552c0..0551a9f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ moshi = "1.15.0" junit = "4.13.2" testRunner = "1.5.2" espressoCore = "3.5.1" +r8 = "8.2.36" [libraries] kotlin-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlinVersion" } @@ -67,3 +68,5 @@ preference-ktx = { group = "androidx.preference", name = "preference-ktx", versi test-runner = { group = "androidx.test", name = "runner", version.ref = "testRunner" } test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } test-junit = { group = "junit", name = "junit", version.ref = "junit" } + +tools-r8 = { module = "com.android.tools:r8", version.ref = "r8" } diff --git a/library/build.gradle.kts b/library/build.gradle.kts index c1c5d9b..d45baeb 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -19,8 +19,9 @@ android { buildTypes { release { - isMinifyEnabled = false + isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + consumerProguardFile("proguard-rules.pro") } } packaging { diff --git a/library/proguard-rules.pro b/library/proguard-rules.pro index 137bfc5..ce997ea 100644 --- a/library/proguard-rules.pro +++ b/library/proguard-rules.pro @@ -15,3 +15,12 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + +-dontwarn java.lang.invoke.StringConcatFactory + +-keep class com.uploadcare.android.library.data.** { *; } +-keep class com.uploadcare.android.library.api.Project { *; } +-keep class com.uploadcare.android.library.api.UploadcareCopyFile { *; } +-keep class com.uploadcare.android.library.api.UploadcareFile { *; } +-keep class com.uploadcare.android.library.api.UploadcareGroup { *; } +-keep class com.uploadcare.android.library.api.UploadcareWebhook { *; } diff --git a/widget/build.gradle.kts b/widget/build.gradle.kts index fffe961..ca8ead0 100644 --- a/widget/build.gradle.kts +++ b/widget/build.gradle.kts @@ -27,9 +27,10 @@ android { buildConfigField("String", "SOCIAL_API_ENDPOINT", "\"https://social.uploadcare.com/\"") } release { - isMinifyEnabled = false + isMinifyEnabled = true buildConfigField("String", "SOCIAL_API_ENDPOINT", "\"https://social.uploadcare.com/\"") proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + consumerProguardFile("proguard-rules.pro") } } diff --git a/widget/proguard-rules.pro b/widget/proguard-rules.pro index 137bfc5..8848c9f 100644 --- a/widget/proguard-rules.pro +++ b/widget/proguard-rules.pro @@ -15,3 +15,21 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + +-keep class com.uploadcare.android.widget.data.** { *; } + +# Keep inherited services. +-if interface * { @retrofit2.http.* ; } +-keep,allowobfuscation interface * extends <1> + +# With R8 full mode generic signatures are stripped for classes that are not +# kept. Suspend functions are wrapped in continuations where the type argument +# is used. +-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation + +# R8 full mode strips generic signatures from return types if not kept. +-if interface * { @retrofit2.http.* public *** *(...); } +-keep,allowoptimization,allowshrinking,allowobfuscation class <3> + +# With R8 full mode generic signatures are stripped for classes that are not kept. +-keep,allowobfuscation,allowshrinking class retrofit2.Response