From 7f8c57c938083e98aab527c34ef710effed4b18e Mon Sep 17 00:00:00 2001 From: MySkeletonHurts <300206351+MySkeletonHurts@users.noreply.github.com> Date: Sun, 13 Sep 2026 19:41:30 -0500 Subject: [PATCH] fix: keep SSO library classes and generic signatures in release builds Adding a Nextcloud account (and every subsequent sync) failed in release builds only, with "Nextcloud returned an empty capabilities response". Debug builds worked fine against the same server and account. The Nextcloud SSO library's NextcloudRetrofitServiceMethod inspects the generic return type of API interface methods reflectively (method.getGenericReturnType()) to decide how to deserialize responses, expecting Observable>. In release builds this resolved to a raw ParsedResponse with the argument erased, so the reflective check silently took a fallback path that deserializes the response as ParsedResponse itself instead of OcsResponse, producing an empty result. Two things were needed to fix it: - -keepattributes Signature, so R8 keeps the generic signature metadata reflection depends on at all. - Keep rules for NextcloudRetrofitServiceMethod and ParsedResponse specifically. Android-SingleSignOn 1.3.4 ships its own consumer proguard rules (which already cover -keepattributes Signature), but they don't keep these two classes, so R8 full mode is still free to rename/optimize them, which corrupts the nested generic signature when remapping it. Verified with a locally-signed release build: without this change the account add reproduces the failure every time; with it, account setup and sync work identically to a debug build. --- app/proguard-rules.pro | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 5923a8b..5ff9b21 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,3 +1,18 @@ +# The Nextcloud SSO library's NextcloudRetrofitServiceMethod inspects generic return types +# reflectively (method.getGenericReturnType()) to decide how to deserialize responses. Without +# this attribute R8 erases that generic signature, the type check silently falls back to a +# different code path, and every SSO-relayed request breaks in release builds only. +-keepattributes Signature + +# Android-SingleSignOn 1.3.4 ships consumer proguard rules of its own (including the +# -keepattributes Signature above), but they don't keep NextcloudRetrofitServiceMethod or +# ParsedResponse themselves, so R8 full mode is still free to rename/optimize them — which +# corrupts the nested generic Signature (Observable> loses its +# inner argument) when it remaps the Signature attribute string. Keep just the +# two classes proven necessary rather than the whole com.nextcloud.android.sso namespace. +-keep class com.nextcloud.android.sso.api.NextcloudRetrofitServiceMethod { *; } +-keep class com.nextcloud.android.sso.api.ParsedResponse { *; } + # Retrofit and Gson access Nextcloud API contracts and payloads reflectively. -keep,allowoptimization interface org.qownnotes.mobile.backend.nextcloud.**Api { *; } -keep,allowoptimization class org.qownnotes.mobile.backend.nextcloud.**Dto { *; }