Skip to content

Commit 737fdd8

Browse files
tianyificbaker
authored andcommitted
Deflake the DefaultPreloadManagerTest
From [ the last change in `DefaultPreloadManagerTest`](2b54b1e), the preloadManager began to use a separate `preloadThread` in `release_returnZeroCount_sourcesAndRendererCapabilitiesListReleased`, which unveils a bug in `PreloadMediaSource`. When `PreloadMediaSource.releasePreloadMediaSource` is called, `preloadHandler` will post a `Runnable` on the preload looper to release the internal resources. Before this `Runnable` is executed, it is possible that the [`stopPreloading`](https://github.com/androidx/media/blob/main/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java#L442) method is executed just as the result of preloading has completed. This is expected to remove the posted `Runnable`s for further preloading, however, the posted `Runnable` for releasing will also be removed from the message queue. Ideally we should use `postDelayed(runnable, token, delayMillis)` to post the runnables so that the token will be useful to identify which messages to remove in `removeCallbacksAndMessages(token)`, but that `postDelayed` method is only available from API 28. So in this change we are using a separate handler for releasing, and then the call of `preloadHandler.removeCallbacksAndMessages` won't impact the runnable for releasing. #cherrypick PiperOrigin-RevId: 696894483 (cherry picked from commit 0143884)
1 parent fd02ee1 commit 737fdd8

File tree

2 files changed

+5
-3
lines changed

2 files changed

+5
-3
lines changed

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ public PreloadMediaSource createMediaSource(MediaSource mediaSource) {
221221
private final RendererCapabilities[] rendererCapabilities;
222222
private final Allocator allocator;
223223
private final Handler preloadHandler;
224+
private final Handler releaseHandler;
224225
private boolean preloadCalled;
225226
private boolean prepareChildSourceCalled;
226227
private long startPositionUs;
@@ -246,6 +247,7 @@ private PreloadMediaSource(
246247
this.allocator = allocator;
247248

248249
preloadHandler = Util.createHandler(preloadLooper, /* callback= */ null);
250+
releaseHandler = Util.createHandler(preloadLooper, /* callback= */ null);
249251
startPositionUs = C.TIME_UNSET;
250252
}
251253

@@ -396,7 +398,7 @@ protected void releaseSourceInternal() {
396398
*

Can be called from any thread.

397399
*/
398400
public void releasePreloadMediaSource() {
399-
preloadHandler.post(
401+
releaseHandler.post(
400402
() -> {
401403
preloadCalled = false;
402404
startPositionUs = C.TIME_UNSET;
@@ -407,6 +409,7 @@ public void releasePreloadMediaSource() {
407409
}
408410
releaseSourceInternal();
409411
preloadHandler.removeCallbacksAndMessages(null);
412+
releaseHandler.removeCallbacksAndMessages(null);
410413
});
411414
}
412415

libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManagerTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,8 +830,7 @@ protected void releaseSourceInternal() {
830830
}
831831

832832
@Test
833-
public void release_returnZeroCount_sourcesAndRendererCapabilitiesListReleased()
834-
throws Exception {
833+
public void release_returnZeroCount_sourcesAndRendererCapabilitiesListReleased() {
835834
TargetPreloadStatusControl<Integer> targetPreloadStatusControl =
836835
rankingData -> new DefaultPreloadManager.Status(STAGE_SOURCE_PREPARED);
837836
MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class);

0 commit comments

Comments
 (0)