Commit 852c3a53 by bachinger Committed by Toni

copy masked timeline before notifying listeners

PiperOrigin-RevId: 270221478
parent a60265b1
...@@ -308,13 +308,11 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -308,13 +308,11 @@ import java.util.concurrent.CopyOnWriteArrayList;
/* fromIndex= */ 0, /* toIndexExclusive= */ mediaSourceHolders.size()); /* fromIndex= */ 0, /* toIndexExclusive= */ mediaSourceHolders.size());
} }
List<Playlist.MediaSourceHolder> holders = addMediaSourceHolders(/* index= */ 0, mediaItems); List<Playlist.MediaSourceHolder> holders = addMediaSourceHolders(/* index= */ 0, mediaItems);
maskTimeline(); Timeline timeline = maskTimeline();
internalPlayer.setMediaItems( internalPlayer.setMediaItems(
holders, startWindowIndex, C.msToUs(startPositionMs), shuffleOrder); holders, startWindowIndex, C.msToUs(startPositionMs), shuffleOrder);
notifyListeners( notifyListeners(
listener -> listener -> listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
listener.onTimelineChanged(
playbackInfo.timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
} }
@Override @Override
...@@ -337,12 +335,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -337,12 +335,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
Assertions.checkArgument(index >= 0); Assertions.checkArgument(index >= 0);
pendingOperationAcks++; pendingOperationAcks++;
List<Playlist.MediaSourceHolder> holders = addMediaSourceHolders(index, mediaSources); List<Playlist.MediaSourceHolder> holders = addMediaSourceHolders(index, mediaSources);
maskTimeline(); Timeline timeline = maskTimeline();
internalPlayer.addMediaItems(index, holders, shuffleOrder); internalPlayer.addMediaItems(index, holders, shuffleOrder);
notifyListeners( notifyListeners(
listener -> listener -> listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
listener.onTimelineChanged(
playbackInfo.timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
} }
@Override @Override
...@@ -374,12 +370,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -374,12 +370,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
pendingOperationAcks++; pendingOperationAcks++;
newFromIndex = Math.min(newFromIndex, mediaSourceHolders.size() - (toIndex - fromIndex)); newFromIndex = Math.min(newFromIndex, mediaSourceHolders.size() - (toIndex - fromIndex));
Playlist.moveMediaSourceHolders(mediaSourceHolders, fromIndex, toIndex, newFromIndex); Playlist.moveMediaSourceHolders(mediaSourceHolders, fromIndex, toIndex, newFromIndex);
maskTimeline(); Timeline timeline = maskTimeline();
internalPlayer.moveMediaItems(fromIndex, toIndex, newFromIndex, shuffleOrder); internalPlayer.moveMediaItems(fromIndex, toIndex, newFromIndex, shuffleOrder);
notifyListeners( notifyListeners(
listener -> listener -> listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
listener.onTimelineChanged(
playbackInfo.timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
} }
@Override @Override
...@@ -394,12 +388,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -394,12 +388,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
public void setShuffleOrder(ShuffleOrder shuffleOrder) { public void setShuffleOrder(ShuffleOrder shuffleOrder) {
pendingOperationAcks++; pendingOperationAcks++;
this.shuffleOrder = shuffleOrder; this.shuffleOrder = shuffleOrder;
maskTimeline(); Timeline timeline = maskTimeline();
internalPlayer.setShuffleOrder(shuffleOrder); internalPlayer.setShuffleOrder(shuffleOrder);
notifyListeners( notifyListeners(
listener -> listener -> listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
listener.onTimelineChanged(
playbackInfo.timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
} }
@Override @Override
...@@ -879,12 +871,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -879,12 +871,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
pendingOperationAcks++; pendingOperationAcks++;
List<Playlist.MediaSourceHolder> mediaSourceHolders = List<Playlist.MediaSourceHolder> mediaSourceHolders =
removeMediaSourceHolders(fromIndex, /* toIndexExclusive= */ toIndex); removeMediaSourceHolders(fromIndex, /* toIndexExclusive= */ toIndex);
maskTimeline(); Timeline timeline = maskTimeline();
internalPlayer.removeMediaItems(fromIndex, toIndex, shuffleOrder); internalPlayer.removeMediaItems(fromIndex, toIndex, shuffleOrder);
notifyListeners( notifyListeners(
listener -> listener -> listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
listener.onTimelineChanged(
playbackInfo.timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
return mediaSourceHolders; return mediaSourceHolders;
} }
...@@ -898,12 +888,13 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -898,12 +888,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
return removed; return removed;
} }
private void maskTimeline() { private Timeline maskTimeline() {
playbackInfo = playbackInfo =
playbackInfo.copyWithTimeline( playbackInfo.copyWithTimeline(
mediaSourceHolders.isEmpty() mediaSourceHolders.isEmpty()
? Timeline.EMPTY ? Timeline.EMPTY
: new Playlist.PlaylistTimeline(mediaSourceHolders, shuffleOrder)); : new Playlist.PlaylistTimeline(mediaSourceHolders, shuffleOrder));
return playbackInfo.timeline;
} }
private void notifyListeners(ListenerInvocation listenerInvocation) { private void notifyListeners(ListenerInvocation listenerInvocation) {
......
...@@ -3097,6 +3097,37 @@ public final class ExoPlayerTest { ...@@ -3097,6 +3097,37 @@ public final class ExoPlayerTest {
} }
@Test @Test
public void testMultipleModificationWithRecursiveListenerInvocations() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
MediaSource mediaSource = new FakeMediaSource(timeline);
Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 2);
MediaSource secondMediaSource = new FakeMediaSource(secondTimeline);
ActionSchedule actionSchedule =
new ActionSchedule.Builder("testMultipleModificationWithRecursiveListenerInvocations")
.waitForTimelineChanged(timeline, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE)
.clearMediaItems()
.setMediaItems(secondMediaSource)
.build();
ExoPlayerTestRunner exoPlayerTestRunner =
new Builder()
.setMediaSources(mediaSource)
.setActionSchedule(actionSchedule)
.build(context)
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertTimelinesSame(
dummyTimeline, timeline, Timeline.EMPTY, dummyTimeline, secondTimeline);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(
Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE,
Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
}
@Test
public void testPrepareWhenAlreadyPreparedIsANoop() throws Exception { public void testPrepareWhenAlreadyPreparedIsANoop() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 1); Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
ActionSchedule actionSchedule = ActionSchedule actionSchedule =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment