ANR while working with EncryptedSharedPreferences
Asked Answered
A

1

6

i am getting ANR in my applications broadcast receiver.

log from google console -

Broadcast of Intent { flg=0x14 cmp=in.medibuddy/.receivers.DailyInitHealthReceiver (has extras) }

Recently i have include EncryptedSharedPreferences by using this library androidx.security:security-crypto:1.0.0. After that i have seen multiple ANR in google console related to app. below log i am able to find in google console.

#00  pc 000000000005589c  /system/lib/libc.so (__ioctl+8)
  #00  pc 0000000000022363  /system/lib/libc.so (ioctl+38)
  #00  pc 000000000003d863  /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+206)
  #00  pc 000000000003e339  /system/lib/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+240)
  #00  pc 000000000003729d  /system/lib/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+36)
  #00  pc 00000000000cacd3  /system/lib/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)+82)
  at android.os.BinderProxy.transactNative (Native method)
  at android.os.BinderProxy.transact (Binder.java:1145)
  at android.security.IKeystoreService$Stub$Proxy.exist (IKeystoreService.java:932)
  at android.security.KeyStore.contains (KeyStore.java:366)
  at android.security.keystore.AndroidKeyStoreSpi.engineContainsAlias (AndroidKeyStoreSpi.java:1037)
  at java.security.KeyStore.containsAlias (KeyStore.java:1293)
  at androidx.security.crypto.MasterKeys.keyExists (MasterKeys.java:137)
  at androidx.security.crypto.MasterKeys.getOrCreate (MasterKeys.java:87)
  at in.medibuddy.util.UserStore.getSecuredPref (UserStore.java:34)
  at in.medibuddy.util.UserStore.getPref (UserStore.java:19)
  at in.medibuddy.MediBuddyApplication.initializeFirebaseAnalytics (MediBuddyApplication.java:211)
  at in.medibuddy.MediBuddyApplication.onCreate (MediBuddyApplication.java:201)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1158)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6304)
  at android.app.ActivityThread.access$1200 (ActivityThread.java:241)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1807)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:214)
  at android.app.ActivityThread.main (ActivityThread.java:7156)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)

can anybody help me, why this is happening ?

Arbela answered 8/7, 2021 at 12:38 Comment(2)
Any solution for this?Stromboli
we are getting a rare ANR in App.onCreate with a similar stack trace.Happ
S
1

This is because Android keystore is not really ok to call from the main thread. EncryptedSharedPreferences uses keystore for encryption.

So why not main thread?

  1. Keystore does crypto "stuff", which can be slow. e.g. RSA key generation can take seconds.
  2. Keystore is extra slow if you're using Strongbox (Android-speak for crypto backed by Secure Element).
  3. Under the covers, keystore does disk I/O, which I think is also a bit of a no-no from the main thread.

In this exactly stack, there's a containsAlias call that seems to be taking some time. Under the covers, this is doing disk I/O to search for keys. On older (pre Android 12) devices, I think this operation can be a bit pokey if the device has a lot of keystore keys on it.

For Android U, keystore APIs are now annotated so that StrictMode will complain if an app calls keystore APIs from the main thread. It looks like this may not yet be publicly documented, but that's fixable! :)


That all said... apps generally don't want to use EncryptedSharedPreferences anyhow. For instance, since EncryptedSharedPreferences are encrypted with keystore, which means they cannot survive factory reset or be transferred to another device (e.g via cloud backup). These things sometimes surprise developers when their users complain that after a cloud restore they lost settings. If this is behavior you want in your app, then go for it! It's just not super typical that people actually want this behavior.

Also consider that Android has file encryption already. Application data is already encrypted with a per-user credential. Adding an additional layer of encryption for preferences doesn't necessarily improve the situation if your intent is that data is never sitting around as plaintext.

Sacristy answered 5/4 at 0:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.