Skip to content

VolumeChangeReceiver triggers an IllegalStateException #10758

Closed
@malbanese

Description

@malbanese

ExoPlayer Version

2.18.1

Devices that reproduce the issue

Devices: Moto, Samsung, Pixel
Android Versions: 12, 13

Devices that do not reproduce the issue

Has not been observed on any android versions under 12

Reproducible in the demo app?

Trying, haven't been able to reproduce

Reproduction steps

I've been able to reproduce it locally by triggering rapid volume changes when exiting playback. I've done it both via spamming ADB commands and also holding the physical volume slider on the phone.

Looking across multiple instances of it occurring, it seems to happen to a non-insignificant number of users after the playback activity / fragments trigger their destroyed lifecycle methods.

It's worth noting that our playback activity is locked to landscape, so users often get configuration changes when exiting it (many users lock their phones in portrait). Reproducing this using the volume method as described above is rather flakey - but as of right now I haven't been able to reproduce while keeping the phone in landscape across both activities.

java.lang.IllegalStateException
    at com.google.android.exoplayer2.util.Assertions.checkState
    at com.google.android.exoplayer2.util.FlagSet$Builder.build(SourceFile:150)
    at com.google.android.exoplayer2.util.ListenerSet$ListenerHolder.release
    at com.google.android.exoplayer2.util.ListenerSet.release(SourceFile:236)
    at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.releaseInternal
    at com.google.android.exoplayer2.StreamVolumeManager$VolumeChangeReceiver$$InternalSyntheticLambda$3$f8a604daa12c21ed8502402f441ed63734c776977dc7c4af3d0e402bf56df29e$0.run$bridge(SourceFile:0)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8751)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Expected result

ExoPlayer would not throw an IllegalStateException after the activity has been destroyed.

Actual result

ExoPlayer occasionally enters a state where an exception is thrown.

Media

N/A

Bug Report

  • You will email the zip file produced by adb bugreport to dev.exoplayer@gmail.com after filing this issue.

Activity

tonihei

tonihei commented on Nov 10, 2022

@tonihei
Collaborator

Do you create or use the player on a background thread that isn't the application main thread by any chance? Or is there anything else noteworthy about how you release the player?

It certainly looks like a bug that this particular IllegalStateException is thrown and I'm trying to understand under which circumstances it can happen.

self-assigned this
on Nov 10, 2022
malbanese

malbanese commented on Nov 10, 2022

@malbanese
Author

@tonihei We're not creating the player from a background thread, to be 100% sure I reproduced it while asserting that it was the main thread. As far as releasing the player, it does happen inside of a fragment's onDestroy method, but when double checking - there's nothing noteworthy happening at the same time.

I verified that our release method does only get called a single time, and to be extra sure it wasn't some strange interaction with our own AnalyticsListener, I also reproduced it without adding it as well.

I've been able to band-aid fix it by cloning the DefaultAnalyticsListener and catching the exception inside the class's releaseInternal method - but its a non-ideal fix, since something strange is obviously happening.

tonihei

tonihei commented on Nov 15, 2022

@tonihei
Collaborator

I tried to reproduce this in the ExoPlayer demo app by manually changing the volume and by programmatically inundating the listener with continuous artificial volume change events. This didn't trigger the problem, so I believe there is something in your setup that make this happen. Can you try to reproduce in the demo app to see what you changes to make this problem appear?

I also tried to analyze the method calls to understand how this exception can possibly happen and found some possibilities that are not directly related to the volume changes. It seems the exception can happen if you overwrite a Player.Listener or AnalyticsListener and from within one of the callbacks call player.release()/removeListener()/removeAnalyticsListener() (or AnalyticsCollector.release()). Even then, the problem only occurs if this callback is followed by another automatic release or listener removal AND there was a pending event to be notified (this could be the volume change).

Could you check your listener implementations to see if/when you call any of these methods? We should also look into fixing this problem, but would be good to understand where it comes from exactly.

tonihei

tonihei commented on Nov 15, 2022

@tonihei
Collaborator

Update: I can reproduce in a unit test that removes a listener from within the onEvents callback (you can probably use any other callback triggered at the same time, like AnalyticsCollector.onReleased). I assume this is what's happening in your app as well. We'll provide a fix for this!

malbanese

malbanese commented on Nov 15, 2022

@malbanese
Author

Aha, thanks for the thorough explanation on how it might be happening! I can definitely double check the cases you've outlined, just for some peace of mind.

8 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @malbanese@google-oss-bot@tonihei

      Issue actions

        VolumeChangeReceiver triggers an IllegalStateException · Issue #10758 · google/ExoPlayer