Giphy / giphy-android-sdk

Home of the GIPHY SDK Android example app, along with Android SDK documentation, issue tracking, & release notes.
https://developers.giphy.com/
Mozilla Public License 2.0
91 stars 40 forks source link

Giphy sdk compatibility with dexguard #185

Closed GauravP123 closed 2 years ago

GauravP123 commented 2 years ago

We are in the process of migrating our codebase to android 12. We have upgraded giphy SDK to 2.1.17 as the older version is not compatible with android 12 When we run the application on debug mode it's working properly as expected. but when we create a release build with dexguard enable it's not loading any gif

ALexanderLonsky commented 2 years ago

@GauravP123 I will try to reproduce it on my end.

Meanwhile, could you please attach a full log?

GauravP123 commented 2 years ago

@ALexanderLonsky We are not getting any errors as such.

 Animated WebP support not set up!, {uri: https://media1.giphy.com/media/{url}/200w.webp?{url} length: 166884}

W/System.err:     at com.giphy.sdk.core.network.api.GPHApiClient$gifById$1$1.run(GPHApiClient.kt:156)

But the same URL is working on debug build

ALexanderLonsky commented 2 years ago

@GauravP123 I see. Could you try to use ImageFormat.GIF instead of WEBP? gifsGridView.imageFormat = ImageFormat.GIF

GauravP123 commented 2 years ago

but the same thing is working on debug build is this expected? And it's working on older giphy sdk

GauravP123 commented 2 years ago
Screenshot 2022-05-03 at 8 02 43 PM

Release build

ALexanderLonsky commented 2 years ago

It is weird. I'll need to check a release build on my end.

ALexanderLonsky commented 2 years ago

@GauravP123 The message is from Fresco:

if (mAnimatedWebPDecoder != null) {
      return mAnimatedWebPDecoder.decode(encodedImage, length, qualityInfo, options);
    }
    throw new DecodeException("Animated WebP support not set up!", encodedImage);

It seems dexguard affects webp in some way.

Could you please try to use GIF image format instead of WEBP?

gifsGridView.imageFormat = ImageFormat.GIF

GauravP123 commented 2 years ago

Any side effect of this?

ALexanderLonsky commented 2 years ago

I am trying to understand if the issue is only with WEBP.

GauravP123 commented 2 years ago

@ALexanderLonsky with gifsGridView.imageFormat = ImageFormat.GIF its showing as a image its not animating. but at least its showing something

ALexanderLonsky commented 2 years ago

Thanks for checking. It's strange. I made a release build with Proguard enabled from the sample app we provide. The grid works just well on my physical device that is running Android 12. I went through Fresco documentation, and the only thing I found is this.

I can't check with dexguard.

I updated Fresco to the latest version in v2.1.17 Could you please check if v2.1.16 works for you?

For that, you need to ensure you are using only the kotlinx-coroutines-androidversion: I had to replace implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") with implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0' otherwise it's crashing.

GauravP123 commented 2 years ago

Getting same error

unknown:ProgressiveDecoder: Animated WebP support not set up!, {uri: https://media4.giphy.com/media/IMEThuEcMIro5QKegQ/200w.webp?cid={value}}, firstEncodedBytes: 52494646748C01005745, length: 101500}
05-04 08:26:41.365 16207 16207 W System.err: com.facebook.imagepipeline.decoder.DecodeException: Animated WebP support not set up!
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.decoder.DefaultImageDecoder.decodeAnimatedWebp(SourceFile:235)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.decoder.DefaultImageDecoder$1.decode(SourceFile:65)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.decoder.DefaultImageDecoder.decode(SourceFile:125)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder.internalDecode(SourceFile:386)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder.doDecode(SourceFile:328)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder.access$400(SourceFile:145)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder$1.run(SourceFile:198)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.JobScheduler.doJob(SourceFile:229)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.JobScheduler.access$000(SourceFile:28)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.producers.JobScheduler$1.run(SourceFile:95)
05-04 08:26:41.365 16207 16207 W System.err:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
05-04 08:26:41.365 16207 16207 W System.err:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
05-04 08:26:41.365 16207 16207 W System.err:    at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(SourceFile:52)
ALexanderLonsky commented 2 years ago

I am sorry to hear that. I can't reproduce the issue on my end, I even obfuscated the SDK using proguard, and tried obfuscated release builds on different devices running Android 12.

I found this, but it should have been resolved in this commit.

Dexguard is a paid solution, probably you should ask them for a fix.

I would suggest trying out our example application with dexguard enabled.

Also, I prepared a fresco_test.zip project that is playing a WEBP at the start, it does not use Giphy SDK, could you try to make a release build with dexguard enabled and see if Fresco is still playing animation?

GauravP123 commented 2 years ago

@ALexanderLonsky if we add-keep class * { *; } in our rules then its works as it does not obfuscate any classes. Can you double-check rules from SDK side or can you share rules so that we can manually add and check

ALexanderLonsky commented 2 years ago

@GauravP123 I don't think it's the Giphy SDK issue. As I said, proguard works for me, it must the issue specifically with dexguard. Animated WebP support not set up! means that dexguard somehow breaks Fresco's image decoder. In the SDK we only add rules for our classes like:

-keep class com.giphy.sdk.core.models.** { *; }
-keep class com.giphy.sdk.core.GPHCore { *; }
-keep class com.giphy.sdk.ui.views.** { *; }

I would suggest keeping Fresco in your rules:

# Do not strip any method/class that is annotated with @DoNotStrip
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.common.internal.DoNotStrip *;
}

or even better: -keep class com.facebook.** { *; }

GauravP123 commented 2 years ago

with -keep class com.facebook.** { *; } it's working but I don't think it's a good idea to skip all facebook classes. Can you help with any particular classes that are required by giphy

ALexanderLonsky commented 2 years ago

we do these imports:

import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.cache.disk.DiskCacheConfig
import com.facebook.common.util.ByteConstants
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.listener.RequestListener
import com.facebook.imagepipeline.listener.RequestLoggingListener
import com.facebook.cache.disk.DiskCacheConfig
import com.facebook.common.util.ByteConstants
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.listener.RequestListener
import com.facebook.imagepipeline.listener.RequestLoggingListener

But we don't use com.facebook.imagepipeline.decoder.ImageDecoder directly, which seems to be the root cause of the issue.

P.S. these are Fresco rules.

GauravP123 commented 2 years ago

Dexguard team suggested following rules and its working

-keep class com.giphy.sdk.core.models.** { *; }
-keep class com.giphy.sdk.core.GPHCore { *; }
-keep class com.giphy.sdk.ui.views.** { *; }
-keep class com.giphy.sdk.ui.Giphy { *; }

# Do not strip any method/class that is annotated with @DoNotStrip
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.common.internal.DoNotStrip *;
}

-keep class com.facebook.image** { *; }
-keep class com.facebook.animated.** { *; }
-keep class com.facebook.fresco.** { *; }
-keep class com.facebook.webpsupport.** { *; }

Thanks for quick help