androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
Apache License 2.0
1.35k stars 320 forks source link

ANR when tap seek to button and play/pause button simultaneously #1197

Open Kyant0 opened 3 months ago

Kyant0 commented 3 months ago

Version

Media3 1.3.0

More version details

No response

Devices that reproduce the issue

Pixel 4 XL (Android 13)

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

  1. Seek to song and play/pause simultaneously in my app.
  2. The app got ANR.

Expected result

It works normally.

Actual result

  at androidx.media3.session.ConnectedControllersManager.getController(ConnectedControllersManager.java:231)
  - waiting to lock <0x0b8f42ff> (a java.lang.Object) held by thread 22
  at androidx.media3.session.MediaSessionStub.queueSessionTaskWithPlayerCommand(MediaSessionStub.java:292)
  at androidx.media3.session.MediaSessionStub.seekToNextMediaItem(MediaSessionStub.java:1418)
  at androidx.media3.session.MediaControllerImplBase.lambda$seekToNextMediaItem$42$androidx-media3-session-MediaControllerImplBase(MediaControllerImplBase.java:1373)
  at androidx.media3.session.MediaControllerImplBase$$ExternalSyntheticLambda5.run(D8$$SyntheticClass:0)
  at androidx.media3.session.MediaControllerImplBase.dispatchRemoteSessionTask(MediaControllerImplBase.java:373)
  at androidx.media3.session.MediaControllerImplBase.dispatchRemoteSessionTaskWithPlayerCommand(MediaControllerImplBase.java:311)
  at androidx.media3.session.MediaControllerImplBase.seekToNextMediaItem(MediaControllerImplBase.java:1372)
  at androidx.media3.session.MediaController.seekToNextMediaItem(MediaController.java:1497)
  at com.kyant.music.core.player.StatefulAudioPlayer$skipToNext$1.invokeSuspend(StatefulAudioPlayer.kt:95)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
  at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
  at android.os.Handler.handleCallback(Handler.java:942)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loopOnce(Looper.java:201)
  at android.os.Looper.loop(Looper.java:288)
  at android.app.ActivityThread.main(ActivityThread.java:7898)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Media

anr_2024-03-19-00-42-14-290.zip

Bug Report

marcbaechinger commented 3 months ago

Thanks for reporting!

I can repro this when I change the session demo app and build the player with an application looper different to the main thread and then call play followed by a seekToNextItem from another handler message:

controller.play()
Handler(Looper.myLooper()!!).post {
  controller.seekToNextMediaItem()
}

We are looking into a fix for this.

I'm not sure how easy it is for your app to do fix with the current version. From the snippet above the only advise I can see is to no call play() simultaneously with another controller call in a immediately following handler message, but instead call this in the same handler message.

Using the main thread as the application thread of the player helps as well, but you have probably chosen to do so for a reason.

I understand this is probably not easily possible depending on the design of an app. It's also not a solution from the library side that should support sending commands that way. I don't think I have a better advise for this now I'm afraid.

We will update this issue when we have more information around a fix for this issue.