devtodev-analytics / unity-sdk

devtodev SDK gen. 2 for Unity (deprecated)
15 stars 1 forks source link

ANR on android in getAdvertisingId #18

Open Gasparfx opened 3 years ago

Gasparfx commented 3 years ago

Hello!

We have ANR in google play console. With this stack:

Thread "UnityMain"
...
  at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza (unavailable)
  at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza (unavailable)
  at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo (unavailable)
  at com.devtodev.core.utils.DeviceHelper.getAdvertisingId (DeviceHelper.java:67)
  at com.unity3d.player.UnityPlayer.nativeRender (Native method)
...

Looks like its not safe to use getAdvertisingId on main thread.

AntonPetrov83 commented 2 years ago

I have installed ANR-WatchDog which crashes the app if main thread was blocked for more than 5000 ms. And I have a lot of these ANR-candidate crashes.

The common scenario for us is main thread is handling our Unity Activity's stop (see this handleStopActivity):

main
       at sun.misc.Unsafe.park(Unsafe.java)
       at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1063)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1358)
       at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:415)
       at com.unity3d.player.UnityPlayer.updateDisplayInternal(:52)
       at com.unity3d.player.UnityPlayer.updateGLDisplay(:5)
       at com.unity3d.player.UnityPlayer.access$1100()
       at com.unity3d.player.UnityPlayer$19.surfaceDestroyed(:4)
       at android.view.SurfaceView.notifySurfaceDestroyed(SurfaceView.java:2025)
       at android.view.SurfaceView.updateSurface(SurfaceView.java:1245)
       at android.view.SurfaceView.setWindowStopped(SurfaceView.java:343)
       at android.view.SurfaceView.surfaceDestroyed(SurfaceView.java:1845)
       at android.view.ViewRootImpl.notifySurfaceDestroyed(ViewRootImpl.java:2374)
       at android.view.ViewRootImpl.setWindowStopped(ViewRootImpl.java:2330)
       at android.view.WindowManagerGlobal.setStoppedState(WindowManagerGlobal.java:741)
       at android.app.Activity.performStop(Activity.java:8432)
       at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:5402)
       at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:5345)
       at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5455)
       at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:40)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:246)
       at android.app.ActivityThread.main(ActivityThread.java:8633)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

And UnityMain thread is waiting for getAdvertisingId() to complete:

UnityMain
       at sun.misc.Unsafe.park(Unsafe.java)
       at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2109)
       at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
       at com.google.android.gms.common.BlockingServiceConnection.getServiceWithTimeout(com.google.android.gms:play-services-basement@@17.6.0:3)
       at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza(:4)
       at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza(:25)
       at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(:47)
       at com.devtodev.core.utils.DeviceHelper.getAdvertisingId(DeviceHelper.java:67)
       at com.unity3d.player.UnityPlayer.nativeRender()
       at com.unity3d.player.UnityPlayer.access$300()
       at com.unity3d.player.UnityPlayer$e$1.handleMessage(:95)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:246)
       at com.unity3d.player.UnityPlayer$e.run(:20)

Please read this SO: https://stackoverflow.com/questions/23379879/advertisingidclient-getadvertisingidinfo-hangs-forever

Possibly it somehow relates to UnityAds thread:

UnityAdsInitializeThread
       at sun.misc.Unsafe.park(Unsafe.java)
       at java.util.concurrent.locks.LockSupport.park(LockSupport.java:190)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2067)
       at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
       at com.unity3d.services.core.device.AdvertisingId$GoogleAdvertisingServiceConnection.getBinder(AdvertisingId.java:188)
       at com.unity3d.services.core.device.AdvertisingId.fetchAdvertisingId(AdvertisingId.java:61)
       at com.unity3d.services.core.device.AdvertisingId.init(AdvertisingId.java:37)
       at com.unity3d.services.core.configuration.CoreModuleConfiguration.resetState(CoreModuleConfiguration.java:47)
       at com.unity3d.services.core.configuration.InitializeThread$InitializeStateReset.execute(InitializeThread.java:205)
       at com.unity3d.services.core.configuration.InitializeThread.run(InitializeThread.java:43)
AntonPetrov83 commented 2 years ago

My guess is this is some sort of a deadlock. I believe that UnityPlayer.updateDisplayInternal() on a main thread waits for UnityMain thread to do some job.