Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task
Kyant0 opened this issue Mar 18, 2024 · 5 comments
Open
1 task

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

Kyant0 opened this issue Mar 18, 2024 · 5 comments
Assignees
Labels

Comments

@Kyant0
Copy link

Kyant0 commented Mar 18, 2024

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

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.
@marcbaechinger
Copy link
Contributor

marcbaechinger commented Mar 27, 2024

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.

@nift4
Copy link

nift4 commented Mar 25, 2025

I've taken a shot at fixing this: #2256 (and while testing I found another issue related to different application thread: #2265)

@marcbaechinger
Copy link
Contributor

Thanks for the pull request. I think adding Future to these methods is only a workaround that doesn't fix the root cause I'm afraid.

I see whether I can find time to look into this asap.

@nift4
Copy link

nift4 commented Mar 25, 2025

Hi @marcbaechinger, based on my investigation, the following sequence of events happens.

  • [main thread] play() submitted
  • [player/application thread] processes play command after postOrRun, taking controller command queue lock
  • [main thread] loops, enters seekToNextMediaItem(), wants to take controller command queue lock in order to queue seek command (but lock held by application thread)
  • [player/application thread] enters onPlayRequested() which needs to call listener method that must be called on main thread, hence post()ing the method and blocking until post runs

However, main thread is still stuck in seekToNextMediaItem and player/application thread is still holding command queue lock waiting for onPlayRequested, then deadlock happens.

My solution uses the existing MediaSessionStub functionality to submit a long-running command using a Future which will set command queue to "flushing" (will not run new commands until this one is done, but allows to queue more commands), but will free the controller command queue lock so that seek command can be added. Then main thread returns to looping because it was able to queue command, and we get our result from onPlayRequested which then completes another future that unsets the flushing state so that next command (seek) will be processed.

I'm not sure if there's any other sensible way to solve it, but I'll wait for your review. Thanks for looking into it!

@nift4
Copy link

nift4 commented Apr 24, 2025

@marcbaechinger Ping as it's been a month since I opened the PR, to keep it on the radar. My apologies if I am too impatient, it's just hard to me to know wheter it fell off the radar or if there's no time for it.

nift4 added a commit to nift4/media that referenced this issue Apr 30, 2025
nift4 added a commit to nift4/media that referenced this issue May 19, 2025
nift4 added a commit to nift4/media that referenced this issue May 21, 2025
nift4 added a commit to nift4/media that referenced this issue May 21, 2025
nift4 added a commit to nift4/media that referenced this issue May 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants