iterable-android-sdk icon indicating copy to clipboard operation
iterable-android-sdk copied to clipboard

Iterable causes ANR

Open baole opened this issue 1 year ago • 3 comments

I have several ANR reports on Play store console which are caused by Iterable SDK

[samsung j2corelte (Galaxy J2 Core)]/[Android 8.1 (SDK 27)]

"main" tid=1 Runnable
  at com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager.createKeyFormat (AesCtrHmacAeadKeyManager.java)
  at com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager.createKeyFormat (AesCtrHmacAeadKeyManager.java)
  at com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager.access$000 (AesCtrHmacAeadKeyManager.java)
  at com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager$2.keyFormats (AesCtrHmacAeadKeyManager.java)
  at com.google.crypto.tink.Registry.registerKeyManager (Registry.java)
  at com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager.register (AesCtrHmacAeadKeyManager.java)
  at com.google.crypto.tink.aead.AeadConfig.register (AeadConfig.java)
  at com.google.crypto.tink.aead.AeadConfig.init (AeadConfig.java)
  at com.google.crypto.tink.aead.AeadConfig.<clinit> (AeadConfig.java)
  at com.google.crypto.tink.aead.AeadConfig.register (AeadConfig.java)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java)
  at com.iterable.iterableapi.IterableKeychain.<init> (IterableKeychain.kt)
  at com.iterable.iterableapi.IterableApi.getKeychain (IterableApi.java)
  at com.iterable.iterableapi.IterableApi.retrieveEmailAndUserId (IterableApi.java)
  at com.iterable.iterableapi.IterableApi.initialize (IterableApi.java)
  at net.tandem.core_new.analytics.IterableHelperImpl.init (IterableHelperImpl.kt)
  at net.tandem.TandemApp.onCreate (TandemApp.kt)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1119)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:5770)
  at android.app.ActivityThread.-wrap1 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1662)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:440)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:810)
"main" tid=1 Runnable
  at com.iterable.iterableapi.IterableAuthManager.scheduleAuthTokenRefresh (IterableAuthManager.java)
  at com.iterable.iterableapi.IterableAuthManager.queueExpirationRefresh (IterableAuthManager.java)
  at com.iterable.iterableapi.IterableApi.retrieveEmailAndUserId (IterableApi.java)
  at com.iterable.iterableapi.IterableApi.initialize (IterableApi.java)
  at net.tandem.core_new.analytics.IterableHelperImpl.init (IterableHelperImpl.kt)
  at net.tandem.TandemApp.onCreate (TandemApp.kt)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1119)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:5770)
  at android.app.ActivityThread.-wrap1 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1662)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:440)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:810)

[samsung a51 (Galaxy A51)][Android 13 (SDK 33)]

at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider (Cipher.java:2787)
  at javax.crypto.Cipher.chooseProvider (Cipher.java:774)
  at javax.crypto.Cipher.init (Cipher.java:1144)
  at javax.crypto.Cipher.init (Cipher.java:1085)
  at com.google.crypto.tink.subtle.PrfAesCmac.compute (PrfAesCmac.java:69)
  at com.google.crypto.tink.subtle.AesSiv.s2v (AesSiv.java:103)
  at com.google.crypto.tink.subtle.AesSiv.encryptDeterministically (AesSiv.java:114)
  at com.google.crypto.tink.daead.DeterministicAeadWrapper$WrappedDeterministicAead.encryptDeterministically (DeterministicAeadWrapper.java:78)
  at androidx.security.crypto.EncryptedSharedPreferences.encryptKey (EncryptedSharedPreferences.java:611)
  at androidx.security.crypto.EncryptedSharedPreferences.getDecryptedObject (EncryptedSharedPreferences.java:546)
  at androidx.security.crypto.EncryptedSharedPreferences.getString (EncryptedSharedPreferences.java)
  at com.iterable.iterableapi.IterableKeychain.getAuthToken (IterableKeychain.kt:105)
  at com.iterable.iterableapi.IterableApi.retrieveEmailAndUserId (IterableApi.java:361)
  at com.iterable.iterableapi.IterableApi.initialize (IterableApi.java:512)
  at net.tandem.core_new.analytics.IterableHelperImpl.init (IterableHelperImpl.kt:118)
  at net.tandem.TandemApp.onCreate (TandemApp.kt:140)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1266)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:7614)
  at android.app.ActivityThread.-$$Nest$mhandleBindApplication (unavailable)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2400)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8757)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)

[Infinix Infinix-X689B (Infinix HOT 10S)][Android 11 (SDK 30)]

#00  pc 0x000000000004b50c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28)
  #01  pc 0x00000000001b07a4  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+148)
  #02  pc 0x0000000000674730  /apex/com.android.art/lib64/libart.so (art::GoToRunnable(art::Thread*)+480)
  #03  pc 0x000000000067450c  /apex/com.android.art/lib64/libart.so (art::JniMethodEnd(unsigned int, art::Thread*)+28)
  at android.os.BinderProxy.transactNative (Native method)
This Binder call may be taking too long, causing the main thread to wait, and triggering the ANR

  at android.os.BinderProxy.transact (BinderProxy.java:559)
  at android.security.keystore.IKeystoreService$Stub$Proxy.begin (IKeystoreService.java:1465)
  at android.security.KeyStore.begin (KeyStore.java:864)
  at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized (AndroidKeyStoreCipherSpiBase.java:248)
  at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit (AndroidKeyStoreCipherSpiBase.java:109)
  at javax.crypto.Cipher.tryTransformWithProvider (Cipher.java:2984)
  at javax.crypto.Cipher.tryCombinations (Cipher.java:2891)
  at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider (Cipher.java:2796)
  at javax.crypto.Cipher.chooseProvider (Cipher.java:773)
  at javax.crypto.Cipher.init (Cipher.java:1143)
  at javax.crypto.Cipher.init (Cipher.java:1084)
  at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encryptInternal (AndroidKeystoreAesGcm.java)
  at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encrypt (AndroidKeystoreAesGcm.java)
  at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.validateAead (AndroidKeystoreKmsClient.java)
  at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.getAead (AndroidKeystoreKmsClient.java)
  at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readMasterkeyDecryptAndParseKeyset (AndroidKeysetManager.java)
  at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build (AndroidKeysetManager.java)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java)
  at com.iterable.iterableapi.IterableKeychain.<init> (IterableKeychain.kt)
  at com.iterable.iterableapi.IterableApi.getKeychain (IterableApi.java)
  at com.iterable.iterableapi.IterableApi.retrieveEmailAndUserId (IterableApi.java)
  at com.iterable.iterableapi.IterableApi.initialize (IterableApi.java)
  at net.tandem.core_new.analytics.IterableHelperImpl.init (IterableHelperImpl.kt)
Your app's code results in the Binder call above. Code that triggers Binder calls should be moved out of the main thread.

  at net.tandem.TandemApp.onCreate (TandemApp.kt)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1198)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:7051)
  at android.app.ActivityThread.access$1600 (ActivityThread.java:257)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2038)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:268)
  at android.app.ActivityThread.main (ActivityThread.java:8017)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:627)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997)

Iterable SDK v3.4.15. It happens on almost any device/any Android version. It's on production app and I couldn't reproduce reliably in my dev environment.

Any tips on how to fix? Can I move IterableApi.initialize to a background thread?

baole avatar Sep 08 '23 08:09 baole

@Ayyanchira https://github.com/Iterable/iterable-android-sdk/pull/635 doesn't fix the issue. The fact is that Iterable SDK uses I/O (read files) when calling IterableApi.initialize(). The below stacktrack is reported by the system when enables StrictMode.

Is it safe to call IterableApi.initialize() in a background thread/coroutine?

  StrictMode policy violation; ~duration=93 ms: android.os.strictmode.DiskReadViolation
  	at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1666)
  	at libcore.io.BlockGuardOs.access(BlockGuardOs.java:74)
  	at libcore.io.ForwardingOs.access(ForwardingOs.java:128)
  	at android.app.ActivityThread$AndroidOs.access(ActivityThread.java:8071)
  	at java.io.UnixFileSystem.checkAccess(UnixFileSystem.java:313)
  	at java.io.File.exists(File.java:813)
  	at android.app.ContextImpl.ensurePrivateDirExists(ContextImpl.java:790)
  	at android.app.ContextImpl.ensurePrivateDirExists(ContextImpl.java:781)
  	at android.app.ContextImpl.getPreferencesDir(ContextImpl.java:737)
  	at android.app.ContextImpl.getSharedPreferencesPath(ContextImpl.java:962)
  	at android.app.ContextImpl.getSharedPreferences(ContextImpl.java:583)
  	at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:221)
  	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readKeysetFromPrefs(AndroidKeysetManager.java:250)
  	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:287)
  	at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:169)
  	at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:130)
  	at com.iterable.iterableapi.IterableKeychain.<init>(IterableKeychain.kt:38)
  	at com.iterable.iterableapi.IterableApi.getKeychain(IterableApi.java:142)
  	at com.iterable.iterableapi.IterableApi.retrieveEmailAndUserId(IterableApi.java:364)
  	at com.iterable.iterableapi.IterableApi.initialize(IterableApi.java:516)
  	at net.tandem.core_new.analytics.IterableHelperImpl.init(IterableHelperImpl.kt:120)
  	at net.tandem.TandemApp.onCreate(TandemApp.kt:161)
  	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
  	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7015)
  	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
  	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2241)
  	at android.os.Handler.dispatchMessage(Handler.java:106)
  	at android.os.Looper.loopOnce(Looper.java:205)
  	at android.os.Looper.loop(Looper.java:294)
  	at android.app.ActivityThread.main(ActivityThread.java:8194)
  	at java.lang.reflect.Method.invoke(Native Method)
  	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
  	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

baole avatar Nov 15 '23 09:11 baole

@baole were you able to resolve this issue? If so, is it possible if you could share how you did it? Thank you!

sgong-pdftron avatar Mar 04 '24 20:03 sgong-pdftron

Hey, we're facing the same issue. I could workaround it easily by moving the IterableApi.initialize() call to a background thread, but could anyone please confirm that it's safe to do so? Thanks!

henieek avatar Apr 05 '24 11:04 henieek