androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.75k stars 418 forks source link

ANR when release media session in main thread #767

Open ChernyshovYuriy opened 1 year ago

ChernyshovYuriy commented 1 year ago

Version

Media3 1.1.1

More version details

This is reported for 1.2.0-beta01.

Devices that reproduce the issue

Android 11, Haier TV, Changhong TV. Application is in background.

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

The Firebase Crashlytics reports this ANR:

main (native):tid=1 systid=6234

00 pc 0x5ddec libc.so (syscall + 28)

01 pc 0x130dd9 libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*) + 88)

02 pc 0x4d8c33 libart.so (art::GoToRunnable(art::Thread*) + 342)

03 pc 0x4d8ab5 libart.so (art::JniMethodEnd(unsigned int, art::Thread*) + 8)

   at android.os.BinderProxy.transactNative(Native method)
   at android.os.BinderProxy.transact(BinderProxy.java:540)
   at android.media.session.ISession$Stub$Proxy.destroySession(ISession.java:547)
   at android.media.session.MediaSession.release(MediaSession.java:408)
   at android.support.v4.media.session.MediaSessionCompat$MediaSessionImplApi21.release(MediaSessionCompat.java:4037)
   at android.support.v4.media.session.MediaSessionCompat.release(MediaSessionCompat.java:773)
   at androidx.media3.session.MediaSessionLegacyStub.release(MediaSessionLegacyStub.java:279)
   at androidx.media3.session.MediaSessionImpl.release(MediaSessionImpl.java:314)
   at androidx.media3.session.MediaSession.release(MediaSession.java:722)
   at com.yuriy.openradio.shared.service.OpenRadioService.onDestroy(OpenRadioService.kt:254)
   at android.app.ActivityThread.handleStopService(ActivityThread.java:4355)
   at android.app.ActivityThread.access$1900(ActivityThread.java:237)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1956)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loop(Looper.java:223)
   at android.app.ActivityThread.main(ActivityThread.java:7656)
   at java.lang.reflect.Method.invoke(Native method)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Screenshot from 2023-10-25 07-04-27

Expected result

I am not sure whether or not session should be release on main thread. Please correct the documentation if necessary.

Actual result

ANR when media session release.

Media

No specific media.

Bug Report

marcbaechinger commented 1 year ago

Thanks for reporting.

Releasing on the main thread is allowed. I don't agree with the author of the error message that says that calling a binder generally needs to be moved off the main thread. It's true that a two-way binder call like ISession.onDestroy() can be blocked by a malicious remote application, but here it's the system that implements the endpoint.

It certainly shouldn't block that long that this triggers a ANR. ISession.destroySession() is implemented here and basically calls through to here. In these two places the session is released. I'm not sure why this takes so long in the case that produces the stack trace above.

Do you see this often and on other devices than the above? As the stack trace above is from analytics, I guess you can't repro to create a bug report?

More out of curiosity: why is the service stopped when the app is in the background on a TV device?

ChernyshovYuriy commented 1 year ago

Not many users affected, only 9, but that is because I applied radical solution - once onDestroy received and all shut down actions are completed:

android.os.Process.killProcess(android.os.Process.myPid())

I know this is anti pattern but good as temporary solution to understand the root cause. I have a timer in the app, i suspect it is triggering destroy while app is playing in background. I dont have much logs to support this but there is no other reason onDestroy invoked in background.

Screenshot from 2023-11-07 14-58-35