mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
Restrict some Handler to current Looper only.
They currently fall back to the main Looper if the current thread doesn't have a Looper. All the changed Handlers are guaranteed to be created on a thread with a Looper (mostly the ExoPlayer playback Looper) and thus can make this stricter assumption. This makes it easier to reason about the code as there are no ambiguities as to which thread the Handler is running on. PiperOrigin-RevId: 317334503
This commit is contained in:
parent
7d66865d20
commit
c5c4c87728
14 changed files with 62 additions and 38 deletions
|
|
@ -393,6 +393,32 @@ public final class Util {
|
|||
return concatenation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Handler} on the current {@link Looper} thread.
|
||||
*
|
||||
* @throws IllegalStateException If the current thread doesn't have a {@link Looper}.
|
||||
*/
|
||||
public static Handler createHandlerForCurrentLooper() {
|
||||
return createHandlerForCurrentLooper(/* callback= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the current {@link
|
||||
* Looper} thread.
|
||||
*
|
||||
* <p>The method accepts partially initialized objects as callback under the assumption that the
|
||||
* Handler won't be used to send messages until the callback is fully initialized.
|
||||
*
|
||||
* @param callback A {@link Handler.Callback}. May be a partially initialized class, or null if no
|
||||
* callback is required.
|
||||
* @return A {@link Handler} with the specified callback on the current {@link Looper} thread.
|
||||
* @throws IllegalStateException If the current thread doesn't have a {@link Looper}.
|
||||
*/
|
||||
public static Handler createHandlerForCurrentLooper(
|
||||
@Nullable Handler.@UnknownInitialization Callback callback) {
|
||||
return createHandler(Assertions.checkStateNotNull(Looper.myLooper()), callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Handler} on the current {@link Looper} thread.
|
||||
*
|
||||
|
|
@ -405,9 +431,10 @@ public final class Util {
|
|||
|
||||
/**
|
||||
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the current {@link
|
||||
* Looper} thread. The method accepts partially initialized objects as callback under the
|
||||
* assumption that the Handler won't be used to send messages until the callback is fully
|
||||
* initialized.
|
||||
* Looper} thread.
|
||||
*
|
||||
* <p>The method accepts partially initialized objects as callback under the assumption that the
|
||||
* Handler won't be used to send messages until the callback is fully initialized.
|
||||
*
|
||||
* <p>If the current thread doesn't have a {@link Looper}, the application's main thread {@link
|
||||
* Looper} is used.
|
||||
|
|
@ -423,9 +450,10 @@ public final class Util {
|
|||
|
||||
/**
|
||||
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the specified {@link
|
||||
* Looper} thread. The method accepts partially initialized objects as callback under the
|
||||
* assumption that the Handler won't be used to send messages until the callback is fully
|
||||
* initialized.
|
||||
* Looper} thread.
|
||||
*
|
||||
* <p>The method accepts partially initialized objects as callback under the assumption that the
|
||||
* Handler won't be used to send messages until the callback is fully initialized.
|
||||
*
|
||||
* @param looper A {@link Looper} to run the callback on.
|
||||
* @param callback A {@link Handler.Callback}. May be a partially initialized class, or null if no
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
|
|||
@CallSuper
|
||||
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
|
||||
this.mediaTransferListener = mediaTransferListener;
|
||||
eventHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
eventHandler = Util.createHandlerForCurrentLooper();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
.onContinueLoadingRequested(ProgressiveMediaPeriod.this);
|
||||
}
|
||||
};
|
||||
handler = Util.createHandlerForCurrentOrMainLooper();
|
||||
handler = Util.createHandlerForCurrentLooper();
|
||||
sampleQueueTrackIds = new TrackId[0];
|
||||
sampleQueues = new SampleQueue[0];
|
||||
pendingResetPositionUs = C.TIME_UNSET;
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
* events on the external event listener thread.
|
||||
*/
|
||||
public ComponentListener() {
|
||||
playerHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
playerHandler = Util.createHandlerForCurrentLooper();
|
||||
}
|
||||
|
||||
/** Releases the component listener. */
|
||||
|
|
|
|||
|
|
@ -1763,7 +1763,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
private final Handler handler;
|
||||
|
||||
public OnFrameRenderedListenerV23(MediaCodec codec) {
|
||||
handler = Util.createHandlerForCurrentOrMainLooper(/* callback= */ this);
|
||||
handler = Util.createHandlerForCurrentLooper(/* callback= */ this);
|
||||
codec.setOnFrameRenderedListener(/* listener= */ this, handler);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ public final class ClippingMediaSourceTest {
|
|||
testRunner.runOnPlaybackThread(
|
||||
() ->
|
||||
clippingMediaSource.addEventListener(
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
new MediaSourceEventListener() {
|
||||
@Override
|
||||
public void onDownstreamFormatChanged(
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
() ->
|
||||
mediaSource.addMediaSource(
|
||||
createFakeMediaSource(),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown));
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -430,7 +430,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
() ->
|
||||
mediaSource.addMediaSources(
|
||||
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown));
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -448,7 +448,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.addMediaSource(
|
||||
/* index */ 0,
|
||||
createFakeMediaSource(),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown));
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -466,7 +466,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.addMediaSources(
|
||||
/* index */ 0,
|
||||
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown));
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -483,9 +483,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
() -> {
|
||||
mediaSource.addMediaSource(createFakeMediaSource());
|
||||
mediaSource.removeMediaSource(
|
||||
/* index */ 0,
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
runnableInvoked::countDown);
|
||||
/* index */ 0, Util.createHandlerForCurrentLooper(), runnableInvoked::countDown);
|
||||
});
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -505,7 +503,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.moveMediaSource(
|
||||
/* fromIndex */ 1, /* toIndex */
|
||||
0,
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown);
|
||||
});
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
|
|
@ -523,9 +521,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
dummyMainThread.runOnMainThread(
|
||||
() ->
|
||||
mediaSource.addMediaSource(
|
||||
createFakeMediaSource(),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
timelineGrabber));
|
||||
createFakeMediaSource(), Util.createHandlerForCurrentLooper(), timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(1);
|
||||
} finally {
|
||||
|
|
@ -544,7 +540,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.addMediaSources(
|
||||
Arrays.asList(
|
||||
new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(2);
|
||||
|
|
@ -564,7 +560,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.addMediaSource(
|
||||
/* index */ 0,
|
||||
createFakeMediaSource(),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(1);
|
||||
|
|
@ -585,7 +581,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
/* index */ 0,
|
||||
Arrays.asList(
|
||||
new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(2);
|
||||
|
|
@ -606,7 +602,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
dummyMainThread.runOnMainThread(
|
||||
() ->
|
||||
mediaSource.removeMediaSource(
|
||||
/* index */ 0, Util.createHandlerForCurrentOrMainLooper(), timelineGrabber));
|
||||
/* index */ 0, Util.createHandlerForCurrentLooper(), timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(0);
|
||||
} finally {
|
||||
|
|
@ -632,7 +628,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.moveMediaSource(
|
||||
/* fromIndex */ 1, /* toIndex */
|
||||
0,
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(2);
|
||||
|
|
@ -654,7 +650,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
mediaSource.moveMediaSource(
|
||||
/* currentIndex= */ 0,
|
||||
/* newIndex= */ 1,
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
callbackCalledCondition::countDown);
|
||||
mediaSource.releaseSource(caller);
|
||||
});
|
||||
|
|
@ -907,7 +903,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner);
|
||||
|
||||
dummyMainThread.runOnMainThread(
|
||||
() -> mediaSource.clear(Util.createHandlerForCurrentOrMainLooper(), timelineGrabber));
|
||||
() -> mediaSource.clear(Util.createHandlerForCurrentLooper(), timelineGrabber));
|
||||
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.isEmpty()).isTrue();
|
||||
|
|
@ -1059,7 +1055,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
() ->
|
||||
mediaSource.setShuffleOrder(
|
||||
new ShuffleOrder.UnshuffledShuffleOrder(/* length= */ 0),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
runnableInvoked::countDown));
|
||||
runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
dummyMainThread.release();
|
||||
|
|
@ -1079,7 +1075,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
() ->
|
||||
mediaSource.setShuffleOrder(
|
||||
new ShuffleOrder.UnshuffledShuffleOrder(/* length= */ 3),
|
||||
Util.createHandlerForCurrentOrMainLooper(),
|
||||
Util.createHandlerForCurrentLooper(),
|
||||
timelineGrabber));
|
||||
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
|
||||
assertThat(timeline.getFirstWindowIndex(/* shuffleModeEnabled= */ true)).isEqualTo(0);
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||
} else {
|
||||
dataSource = manifestDataSourceFactory.createDataSource();
|
||||
loader = new Loader("Loader:DashMediaSource");
|
||||
handler = Util.createHandlerForCurrentOrMainLooper();
|
||||
handler = Util.createHandlerForCurrentLooper();
|
||||
startLoadingManifest();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
|||
this.allocator = allocator;
|
||||
|
||||
manifestPublishTimeToExpiryTimeUs = new TreeMap<>();
|
||||
handler = Util.createHandlerForCurrentOrMainLooper(/* callback= */ this);
|
||||
handler = Util.createHandlerForCurrentLooper(/* callback= */ this);
|
||||
decoder = new EventMessageDecoder();
|
||||
lastLoadedChunkEndTimeUs = C.TIME_UNSET;
|
||||
lastLoadedChunkEndTimeBeforeRefreshUs = C.TIME_UNSET;
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
@SuppressWarnings("nullness:methodref.receiver.bound.invalid")
|
||||
Runnable onTracksEndedRunnable = this::onTracksEnded;
|
||||
this.onTracksEndedRunnable = onTracksEndedRunnable;
|
||||
handler = Util.createHandlerForCurrentOrMainLooper();
|
||||
handler = Util.createHandlerForCurrentLooper();
|
||||
lastSeekPositionUs = positionUs;
|
||||
pendingResetPositionUs = positionUs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public final class DefaultHlsPlaylistTracker
|
|||
Uri initialPlaylistUri,
|
||||
EventDispatcher eventDispatcher,
|
||||
PrimaryPlaylistListener primaryPlaylistListener) {
|
||||
this.playlistRefreshHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
this.playlistRefreshHandler = Util.createHandlerForCurrentLooper();
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.primaryPlaylistListener = primaryPlaylistListener;
|
||||
ParsingLoadable<HlsPlaylist> masterPlaylistLoadable =
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ public final class SsMediaSource extends BaseMediaSource
|
|||
manifestDataSource = manifestDataSourceFactory.createDataSource();
|
||||
manifestLoader = new Loader("Loader:Manifest");
|
||||
manifestLoaderErrorThrower = manifestLoader;
|
||||
manifestRefreshHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
manifestRefreshHandler = Util.createHandlerForCurrentLooper();
|
||||
startLoadingManifest();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||
/* mediaEndTimeUs = */ C.TIME_UNSET);
|
||||
prepareCallback = callback;
|
||||
if (deferOnPrepared) {
|
||||
playerHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
playerHandler = Util.createHandlerForCurrentLooper();
|
||||
} else {
|
||||
finishPreparation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
drmSessionManager.prepare();
|
||||
preparedSource = true;
|
||||
releasedSource = false;
|
||||
sourceInfoRefreshHandler = Util.createHandlerForCurrentOrMainLooper();
|
||||
sourceInfoRefreshHandler = Util.createHandlerForCurrentLooper();
|
||||
if (timeline != null) {
|
||||
finishSourcePreparation(/* sendManifestLoadEvents= */ true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue