urbanairship / android-library

Urban Airship Android SDK
Other
112 stars 123 forks source link

ANR from com.urbanairship.util.PropertiesConfigParser.fromAssets (PropertiesConfigParser.java) #231

Closed wezley98 closed 1 year ago

wezley98 commented 1 year ago

Preliminary Info

What Airship dependencies are you using?

airship-fcm = { module = "com.urbanairship.android:urbanairship-fcm", version = "17.3.0" }

What are the versions of any relevant development tools you are using?

Firebase Crashlytics Console

Report

What unexpected behavior are you seeing?

ANR reported in Firebase for multiple devices.

Screenshot 2023-10-06 at 15 43 44
main (native):tid=1 systid=12381 
#00 pc 0x9aed4 libc.so (pread64 + 20)
#01 pc 0xb9eb libbase.so (android::base::ReadFullyAtOffset(android::base::borrowed_fd, void*, unsigned int, long long) + 28)
#02 pc 0x770d libziparchive.so (MappedZipFile::ReadAtOffset(unsigned char*, unsigned int, long long) const + 280)
#03 pc 0x68eb libziparchive.so (FindEntry(ZipArchive const*, int, ZipEntry*) + 190)
#04 pc 0x6d33 libziparchive.so (Next(void*, ZipEntry*, std::__1::basic_string_view<char, std::__1::char_traits<char> >*) + 194)
#05 pc 0x6bb3 libziparchive.so (Next(void*, ZipEntry*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) + 30)
#06 pc 0x25135 libandroidfw.so (android::ZipAssetsProvider::ForEachFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<void (android::BasicStringPiece<char> const&, android::FileType)> const&) const + 244)
#07 pc 0x2c915 libandroidfw.so (android::AssetManager2::OpenDir(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const + 148)
#08 pc 0xc412d libandroid_runtime.so (android::NativeList(_JNIEnv*, _jclass*, long long, _jstring*) + 212)
       at android.content.res.AssetManager.nativeList(Native method)
       at android.content.res.AssetManager.list(AssetManager.java:962)
       at com.urbanairship.util.PropertiesConfigParser.fromAssets(PropertiesConfigParser.java)
       at com.urbanairship.AirshipConfigOptions$Builder.tryApplyProperties(AirshipConfigOptions.java:772)
       at com.urbanairship.AirshipConfigOptions$Builder.applyProperties(AirshipConfigOptions.java:752)
       at com.urbanairship.AirshipConfigOptions$Builder.applyDefaultProperties(AirshipConfigOptions.java)
       at com.sky.sport.notifications.NotificationsManager.initialise(NotificationsManager.kt)
       at com.sky.sport.group.App.onCreate(App.kt)
       at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1191)
       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6903)
       at android.app.ActivityThread.access$1600(ActivityThread.java:250)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2008)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:236)
       at android.app.ActivityThread.main(ActivityThread.java:7912)
       at java.lang.reflect.Method.invoke(Native method)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

What is the expected behavior?

No ANR, Can we move the loading of the assets file onto a background thread in the SDK please?

rlepinski commented 1 year ago

How are you calling takeOff? If you use Autopilot and don't provide a config or call takeOff without a config, it will load the properties file in the background. You can also define the config programmatically to avoid the properties file read.

wezley98 commented 1 year ago

How are you calling takeOff? If you use Autopilot and don't provide a config or call takeOff without a config, it will load the properties file in the background. You can also define the config programmatically to avoid the properties file read.

Hi @rlepinski , We call with the following code during application class onCreate()

fun initialise(application: Application, inProduction: Boolean) {
        val options = AirshipConfigOptions.Builder()
            .applyDefaultProperties(application)
            .setInProduction(inProduction)
            .build()

        val onReadyCallback = OnReadyCallback { airship ->
            airship.pushManager.userNotificationsEnabled = true
            airship.pushManager.notificationProvider = NotificationProvider(application, options)

            val notificationHandler = NotificationHandler(application)
            val airshipListener = AirshipListener(notificationHandler)
            airship.pushManager.addPushListener(airshipListener)
            airship.pushManager.addPushTokenListener(airshipListener)
            airship.pushManager.notificationListener = airshipListener
            airship.channel.addChannelListener(airshipListener)
        }

        UAirship.takeOff(application, options, onReadyCallback)
    }

We have an assets file in app/src/main/assets/airshipconfig.properties with our keys.

Should we move to doing this via code instead to avoid this ANR?

rlepinski commented 1 year ago

This is the problematic line: .applyDefaultProperties(application). You have a few options for a quick fix:

wezley98 commented 1 year ago

This is the problematic line: .applyDefaultProperties(application). You have a few options for a quick fix:

  • Create two airshipconfig.properties files, one in release and one in debug that has the inProduction set properly
  • Maybe just remove the options in the call completely since we by default will try to detect inProduction based on a debug flag set in the manifest (automatic for most apps)
  • Hardcode the config and avoid trying to load the default properties

Thanks we'll look into those options. Feel free to close if no upstream fix is needed.