-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Ordering of AnalyticsListener causes assert in PlaybackStatsListener #8048
Comments
This version includes all playback state related metrics and the general listener set-up. PiperOrigin-RevId: 250668729
Thanks! I'm able to reproduce that. In theory, all The problem is that Similar cases may arise if other non-
The callback for The fix is to use the same queue mechanism we have for |
Yes, that sounds exactly correct. Pretty much every
EventQueue design carries the assumption that reentrance is prevented.
Thanks, glad it was possible to reproduce
…On Wed, Oct 7, 2020 at 9:21 AM tonihei ***@***.***> wrote:
Thanks! I'm able to reproduce that.
In theory, all Player.EventListener callbacks should always arrive in the
order in which they are called even if they are called from the callbacks
themselves. We even have an internal notification queue to resolve this
notification recursion.
The problem is that PlaybackStatsListener is listening to onSeekStarted
which is called from SimpleExoPlayer and is not channeled through our
listener notification queue (because it's not part of Player.EventListener,
only AnalyticsListener).
Similar cases may arise if other non-Player.EventListener callbacks are
triggered in another callback. For example:
@OverRide
public void onPlayerError(EventTime eventTime, ExoPlaybackException error) {
simpleExoPlayer.clearVideoSurface();
}
The callback for onSurfaceSizeChanged(eventTime, 0, 0) will also arrive
before the onPlayerError for AnalyticsListeners that are later in the
list.
The fix is to use the same queue mechanism we have for
Player.EventListener for the AnalyticsListener callbacks as well. Once
we've done that the assertion in PlaybackStatsListener failing in your
example shouldn't possibly fail anymore.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#8048 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADBF6GGSGIYX3GWYXHZ5VDSJSIQ7ANCNFSM4SGRS4SA>
.
|
As a more general point, I would argue that |
Thanks @ojw28, excellent point. We have been implementing @tonihei the So the order (on error) would be:
This sequence prevents the bug. If you do anything to "fix" this bug, I would either:
@Override
public final void onPlayerError(ExoPlaybackException error) {
@Player.State int preDispatchState = player.getPlaybackState();
EventTime eventTime = generateLastReportedPlayingMediaPeriodEventTime();
for (AnalyticsListener listener : listeners) {
listener.onPlayerError(eventTime, error);
}
Assertions.checkArgument(preDispatchState == player.getPlaybackState(),
"State altered by AnalyticsListner, Use Player.EventListener for error recovery");
}
@tonihei This error recovery works against what Your guys call, with @ojw28 suggestion I've worked around the bug... But, don't miss the chance to stop someone else from stepping in this hole, it is easy to miss (I did, and I've looked at a lot of ExoPlayer code). If you choose to do 2, here's a pull #8068 (might want to do something on the method too). Option 1 might catch people off guard that have this working by shear luck. |
This is implied by the name and may not have been the original intention, but I wouldn't argue it's not expected. Especially in cases where apps want to combine multiple types of listeners together and/or are interested in the By this argument, I'd be in favour of solving the original problem instead of documenting it's not supported (people won't read that) or asserting it (that will annoy people unnecessarily).
The session doesn't end on error if I remember correctly. It only ends once you set new media items on the player or call |
I do think people read documentation, especially to get the general flavor of things that you can't get without a pretty deep inspection of the code (like when to use what listeners). @tonihei Looks like fixing it is pretty simple (especially if it's just the seek, which is the original issue) then definitely you should do it. |
This ensures recursively sent events arrive in the correct order. Issue: #8048 PiperOrigin-RevId: 337812882
Issue was fixed by the commit above. |
Issue description
The
PlaybackStatsListener
should work correctly no matter what order it is added to theSimpleExoPlayer.addAnalyticsListener()
in relation to otherAnalyticsListener
objects.Reproduction steps
Sorry I don't have an easy example to share, but here is a code sample that will reproduce the issue:
The recovery "seek's" past the error (assume something in the error tells it where to seek too).
PlaybackStatsListener now will field the onPlayerError() event after the seek, see the comment in the PlaybackStatsListener commit
The assertion that fails is marked here
Seems this check implies a seek during error handling is a legit thing:
But the assert here assumes events are delivered in order, which in this case they are not:
Link to test content
Sorry I don't have any, but content that fails with a 404 on a segment would do it. Anything that creates a PlayerError.
A full bug report captured from the device
Probably not that useful.
Version of ExoPlayer being used
r2.11.8
Device(s) and version(s) of Android being used
Arris STB running Android P
The text was updated successfully, but these errors were encountered: