Add DownloadManager.getApplicationLooper

This is equivalent to the method ExoPlayer provides. It's nice for consistency,
and for retrieving the looper from test code.

PiperOrigin-RevId: 308830288
This commit is contained in:
olly 2020-04-28 16:45:32 +01:00 committed by Oliver Woodman
parent c746885ca2
commit 528104919f
4 changed files with 39 additions and 30 deletions

View file

@ -153,14 +153,14 @@ public final class ExoPlayerFactory {
RenderersFactory renderersFactory,
TrackSelector trackSelector,
LoadControl loadControl,
Looper looper) {
Looper applicationLooper) {
return newSimpleInstance(
context,
renderersFactory,
trackSelector,
loadControl,
new AnalyticsCollector(Clock.DEFAULT),
looper);
applicationLooper);
}
/** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */
@ -172,7 +172,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector,
LoadControl loadControl,
AnalyticsCollector analyticsCollector,
Looper looper) {
Looper applicationLooper) {
return newSimpleInstance(
context,
renderersFactory,
@ -180,7 +180,7 @@ public final class ExoPlayerFactory {
loadControl,
DefaultBandwidthMeter.getSingletonInstance(context),
analyticsCollector,
looper);
applicationLooper);
}
/** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */
@ -193,7 +193,7 @@ public final class ExoPlayerFactory {
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector,
Looper looper) {
Looper applicationLooper) {
return new SimpleExoPlayer(
context,
renderersFactory,
@ -204,7 +204,7 @@ public final class ExoPlayerFactory {
analyticsCollector,
/* useLazyPreparation= */ true,
Clock.DEFAULT,
looper);
applicationLooper);
}
/** @deprecated Use {@link ExoPlayer.Builder} instead. */
@ -231,14 +231,14 @@ public final class ExoPlayerFactory {
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
Looper looper) {
Looper applicationLooper) {
return newInstance(
context,
renderers,
trackSelector,
loadControl,
DefaultBandwidthMeter.getSingletonInstance(context),
looper);
applicationLooper);
}
/** @deprecated Use {@link ExoPlayer.Builder} instead. */
@ -249,7 +249,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
Looper looper) {
Looper applicationLooper) {
return new ExoPlayerImpl(
renderers,
trackSelector,
@ -259,6 +259,6 @@ public final class ExoPlayerFactory {
/* analyticsCollector= */ null,
/* useLazyPreparation= */ true,
Clock.DEFAULT,
looper);
applicationLooper);
}
}

View file

@ -65,7 +65,7 @@ import java.util.concurrent.TimeoutException;
private final Renderer[] renderers;
private final TrackSelector trackSelector;
private final Handler eventHandler;
private final Handler applicationHandler;
private final ExoPlayerImplInternal internalPlayer;
private final Handler internalPlayerHandler;
private final CopyOnWriteArrayList<ListenerHolder> listeners;
@ -110,8 +110,8 @@ import java.util.concurrent.TimeoutException;
* loads and other initial preparation steps happen immediately. If true, these initial
* preparations are triggered only when the player starts buffering the media.
* @param clock The {@link Clock}.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
* @param applicationLooper The {@link Looper} that must be used for all calls to the player and
* which is used to call listeners on.
*/
@SuppressLint("HandlerLeak")
public ExoPlayerImpl(
@ -123,7 +123,7 @@ import java.util.concurrent.TimeoutException;
@Nullable AnalyticsCollector analyticsCollector,
boolean useLazyPreparation,
Clock clock,
Looper looper) {
Looper applicationLooper) {
Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " ["
+ ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "]");
Assertions.checkState(renderers.length > 0);
@ -144,8 +144,8 @@ import java.util.concurrent.TimeoutException;
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
seekParameters = SeekParameters.DEFAULT;
maskingWindowIndex = C.INDEX_UNSET;
eventHandler =
new Handler(looper) {
applicationHandler =
new Handler(applicationLooper) {
@Override
public void handleMessage(Message msg) {
ExoPlayerImpl.this.handleEvent(msg);
@ -166,7 +166,7 @@ import java.util.concurrent.TimeoutException;
repeatMode,
shuffleModeEnabled,
analyticsCollector,
eventHandler,
applicationHandler,
clock);
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
}
@ -232,7 +232,7 @@ import java.util.concurrent.TimeoutException;
@Override
public Looper getApplicationLooper() {
return eventHandler.getLooper();
return applicationHandler.getLooper();
}
@Override
@ -568,7 +568,7 @@ import java.util.concurrent.TimeoutException;
// general because the midroll ad preceding the seek destination must be played before the
// content position can be played, if a different ad is playing at the moment.
Log.w(TAG, "seekTo ignored because an ad is playing");
eventHandler
applicationHandler
.obtainMessage(
ExoPlayerImplInternal.MSG_PLAYBACK_INFO_CHANGED,
/* operationAcks */ 1,
@ -690,7 +690,7 @@ import java.util.concurrent.TimeoutException;
ExoPlaybackException.createForUnexpected(
new RuntimeException(new TimeoutException("Player release timed out.")))));
}
eventHandler.removeCallbacksAndMessages(null);
applicationHandler.removeCallbacksAndMessages(null);
playbackInfo =
getResetPlaybackInfo(
/* clearPlaylist= */ false,

View file

@ -343,7 +343,6 @@ public class SimpleExoPlayer extends BasePlayer
protected final Renderer[] renderers;
private final ExoPlayerImpl player;
private final Handler eventHandler;
private final ComponentListener componentListener;
private final CopyOnWriteArraySet<com.google.android.exoplayer2.video.VideoListener>
videoListeners;
@ -420,8 +419,8 @@ public class SimpleExoPlayer extends BasePlayer
* preparations are triggered only when the player starts buffering the media.
* @param clock The {@link Clock} that will be used by the instance. Should always be {@link
* Clock#DEFAULT}, unless the player is being used from a test.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
* @param applicationLooper The {@link Looper} which must be used for all calls to the player and
* which is used to call listeners on.
*/
protected SimpleExoPlayer(
Context context,
@ -433,7 +432,7 @@ public class SimpleExoPlayer extends BasePlayer
AnalyticsCollector analyticsCollector,
boolean useLazyPreparation,
Clock clock,
Looper looper) {
Looper applicationLooper) {
this.bandwidthMeter = bandwidthMeter;
this.analyticsCollector = analyticsCollector;
componentListener = new ComponentListener();
@ -444,7 +443,7 @@ public class SimpleExoPlayer extends BasePlayer
deviceListeners = new CopyOnWriteArraySet<>();
videoDebugListeners = new CopyOnWriteArraySet<>();
audioDebugListeners = new CopyOnWriteArraySet<>();
eventHandler = new Handler(looper);
Handler eventHandler = new Handler(applicationLooper);
renderers =
renderersFactory.createRenderers(
eventHandler,
@ -471,7 +470,7 @@ public class SimpleExoPlayer extends BasePlayer
analyticsCollector,
useLazyPreparation,
clock,
looper);
applicationLooper);
analyticsCollector.setPlayer(player);
player.addListener(analyticsCollector);
player.addListener(componentListener);

View file

@ -62,7 +62,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
*
* <p>A download manager instance must be accessed only from the thread that created it, unless that
* thread does not have a {@link Looper}. In that case, it must be accessed only from the
* application's main thread. Registered listeners will be called on the same thread.
* application's main thread. Registered listeners will be called on the same thread. In all cases
* the `Looper` of the thread from which the manager must be accessed can be queried using {@link
* #getApplicationLooper()}.
*/
public final class DownloadManager {
@ -167,7 +169,7 @@ public final class DownloadManager {
private final Context context;
private final WritableDownloadIndex downloadIndex;
private final Handler mainHandler;
private final Handler applicationHandler;
private final InternalHandler internalHandler;
private final RequirementsWatcher.Listener requirementsListener;
private final CopyOnWriteArraySet<Listener> listeners;
@ -224,7 +226,7 @@ public final class DownloadManager {
@SuppressWarnings("methodref.receiver.bound.invalid")
Handler mainHandler = Util.createHandler(this::handleMainMessage);
this.mainHandler = mainHandler;
this.applicationHandler = mainHandler;
HandlerThread internalThread = new HandlerThread("ExoPlayer:DownloadManager");
internalThread.start();
internalHandler =
@ -250,6 +252,14 @@ public final class DownloadManager {
.sendToTarget();
}
/**
* Returns the {@link Looper} associated with the application thread that's used to access the
* manager, and on which the manager will call its {@link Listener Listeners}.
*/
public Looper getApplicationLooper() {
return applicationHandler.getLooper();
}
/** Returns whether the manager has completed initialization. */
public boolean isInitialized() {
return initialized;
@ -488,7 +498,7 @@ public final class DownloadManager {
// Restore the interrupted status.
Thread.currentThread().interrupt();
}
mainHandler.removeCallbacksAndMessages(/* token= */ null);
applicationHandler.removeCallbacksAndMessages(/* token= */ null);
// Reset state.
downloads = Collections.emptyList();
pendingMessages = 0;