Commit 52810491 by olly Committed by Oliver Woodman

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
parent c746885c
...@@ -153,14 +153,14 @@ public final class ExoPlayerFactory { ...@@ -153,14 +153,14 @@ public final class ExoPlayerFactory {
RenderersFactory renderersFactory, RenderersFactory renderersFactory,
TrackSelector trackSelector, TrackSelector trackSelector,
LoadControl loadControl, LoadControl loadControl,
Looper looper) { Looper applicationLooper) {
return newSimpleInstance( return newSimpleInstance(
context, context,
renderersFactory, renderersFactory,
trackSelector, trackSelector,
loadControl, loadControl,
new AnalyticsCollector(Clock.DEFAULT), new AnalyticsCollector(Clock.DEFAULT),
looper); applicationLooper);
} }
/** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */ /** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */
...@@ -172,7 +172,7 @@ public final class ExoPlayerFactory { ...@@ -172,7 +172,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector, TrackSelector trackSelector,
LoadControl loadControl, LoadControl loadControl,
AnalyticsCollector analyticsCollector, AnalyticsCollector analyticsCollector,
Looper looper) { Looper applicationLooper) {
return newSimpleInstance( return newSimpleInstance(
context, context,
renderersFactory, renderersFactory,
...@@ -180,7 +180,7 @@ public final class ExoPlayerFactory { ...@@ -180,7 +180,7 @@ public final class ExoPlayerFactory {
loadControl, loadControl,
DefaultBandwidthMeter.getSingletonInstance(context), DefaultBandwidthMeter.getSingletonInstance(context),
analyticsCollector, analyticsCollector,
looper); applicationLooper);
} }
/** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */ /** @deprecated Use {@link SimpleExoPlayer.Builder} instead. */
...@@ -193,7 +193,7 @@ public final class ExoPlayerFactory { ...@@ -193,7 +193,7 @@ public final class ExoPlayerFactory {
LoadControl loadControl, LoadControl loadControl,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector, AnalyticsCollector analyticsCollector,
Looper looper) { Looper applicationLooper) {
return new SimpleExoPlayer( return new SimpleExoPlayer(
context, context,
renderersFactory, renderersFactory,
...@@ -204,7 +204,7 @@ public final class ExoPlayerFactory { ...@@ -204,7 +204,7 @@ public final class ExoPlayerFactory {
analyticsCollector, analyticsCollector,
/* useLazyPreparation= */ true, /* useLazyPreparation= */ true,
Clock.DEFAULT, Clock.DEFAULT,
looper); applicationLooper);
} }
/** @deprecated Use {@link ExoPlayer.Builder} instead. */ /** @deprecated Use {@link ExoPlayer.Builder} instead. */
...@@ -231,14 +231,14 @@ public final class ExoPlayerFactory { ...@@ -231,14 +231,14 @@ public final class ExoPlayerFactory {
Renderer[] renderers, Renderer[] renderers,
TrackSelector trackSelector, TrackSelector trackSelector,
LoadControl loadControl, LoadControl loadControl,
Looper looper) { Looper applicationLooper) {
return newInstance( return newInstance(
context, context,
renderers, renderers,
trackSelector, trackSelector,
loadControl, loadControl,
DefaultBandwidthMeter.getSingletonInstance(context), DefaultBandwidthMeter.getSingletonInstance(context),
looper); applicationLooper);
} }
/** @deprecated Use {@link ExoPlayer.Builder} instead. */ /** @deprecated Use {@link ExoPlayer.Builder} instead. */
...@@ -249,7 +249,7 @@ public final class ExoPlayerFactory { ...@@ -249,7 +249,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector, TrackSelector trackSelector,
LoadControl loadControl, LoadControl loadControl,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
Looper looper) { Looper applicationLooper) {
return new ExoPlayerImpl( return new ExoPlayerImpl(
renderers, renderers,
trackSelector, trackSelector,
...@@ -259,6 +259,6 @@ public final class ExoPlayerFactory { ...@@ -259,6 +259,6 @@ public final class ExoPlayerFactory {
/* analyticsCollector= */ null, /* analyticsCollector= */ null,
/* useLazyPreparation= */ true, /* useLazyPreparation= */ true,
Clock.DEFAULT, Clock.DEFAULT,
looper); applicationLooper);
} }
} }
...@@ -65,7 +65,7 @@ import java.util.concurrent.TimeoutException; ...@@ -65,7 +65,7 @@ import java.util.concurrent.TimeoutException;
private final Renderer[] renderers; private final Renderer[] renderers;
private final TrackSelector trackSelector; private final TrackSelector trackSelector;
private final Handler eventHandler; private final Handler applicationHandler;
private final ExoPlayerImplInternal internalPlayer; private final ExoPlayerImplInternal internalPlayer;
private final Handler internalPlayerHandler; private final Handler internalPlayerHandler;
private final CopyOnWriteArrayList<ListenerHolder> listeners; private final CopyOnWriteArrayList<ListenerHolder> listeners;
...@@ -110,8 +110,8 @@ import java.util.concurrent.TimeoutException; ...@@ -110,8 +110,8 @@ import java.util.concurrent.TimeoutException;
* loads and other initial preparation steps happen immediately. If true, these initial * loads and other initial preparation steps happen immediately. If true, these initial
* preparations are triggered only when the player starts buffering the media. * preparations are triggered only when the player starts buffering the media.
* @param clock The {@link Clock}. * @param clock The {@link Clock}.
* @param looper The {@link Looper} which must be used for all calls to the player and which is * @param applicationLooper The {@link Looper} that must be used for all calls to the player and
* used to call listeners on. * which is used to call listeners on.
*/ */
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
public ExoPlayerImpl( public ExoPlayerImpl(
...@@ -123,7 +123,7 @@ import java.util.concurrent.TimeoutException; ...@@ -123,7 +123,7 @@ import java.util.concurrent.TimeoutException;
@Nullable AnalyticsCollector analyticsCollector, @Nullable AnalyticsCollector analyticsCollector,
boolean useLazyPreparation, boolean useLazyPreparation,
Clock clock, Clock clock,
Looper looper) { Looper applicationLooper) {
Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " [" Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " ["
+ ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "]"); + ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "]");
Assertions.checkState(renderers.length > 0); Assertions.checkState(renderers.length > 0);
...@@ -144,8 +144,8 @@ import java.util.concurrent.TimeoutException; ...@@ -144,8 +144,8 @@ import java.util.concurrent.TimeoutException;
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED; playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
seekParameters = SeekParameters.DEFAULT; seekParameters = SeekParameters.DEFAULT;
maskingWindowIndex = C.INDEX_UNSET; maskingWindowIndex = C.INDEX_UNSET;
eventHandler = applicationHandler =
new Handler(looper) { new Handler(applicationLooper) {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
ExoPlayerImpl.this.handleEvent(msg); ExoPlayerImpl.this.handleEvent(msg);
...@@ -166,7 +166,7 @@ import java.util.concurrent.TimeoutException; ...@@ -166,7 +166,7 @@ import java.util.concurrent.TimeoutException;
repeatMode, repeatMode,
shuffleModeEnabled, shuffleModeEnabled,
analyticsCollector, analyticsCollector,
eventHandler, applicationHandler,
clock); clock);
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper()); internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
} }
...@@ -232,7 +232,7 @@ import java.util.concurrent.TimeoutException; ...@@ -232,7 +232,7 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public Looper getApplicationLooper() { public Looper getApplicationLooper() {
return eventHandler.getLooper(); return applicationHandler.getLooper();
} }
@Override @Override
...@@ -568,7 +568,7 @@ import java.util.concurrent.TimeoutException; ...@@ -568,7 +568,7 @@ import java.util.concurrent.TimeoutException;
// general because the midroll ad preceding the seek destination must be played before the // 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. // content position can be played, if a different ad is playing at the moment.
Log.w(TAG, "seekTo ignored because an ad is playing"); Log.w(TAG, "seekTo ignored because an ad is playing");
eventHandler applicationHandler
.obtainMessage( .obtainMessage(
ExoPlayerImplInternal.MSG_PLAYBACK_INFO_CHANGED, ExoPlayerImplInternal.MSG_PLAYBACK_INFO_CHANGED,
/* operationAcks */ 1, /* operationAcks */ 1,
...@@ -690,7 +690,7 @@ import java.util.concurrent.TimeoutException; ...@@ -690,7 +690,7 @@ import java.util.concurrent.TimeoutException;
ExoPlaybackException.createForUnexpected( ExoPlaybackException.createForUnexpected(
new RuntimeException(new TimeoutException("Player release timed out."))))); new RuntimeException(new TimeoutException("Player release timed out.")))));
} }
eventHandler.removeCallbacksAndMessages(null); applicationHandler.removeCallbacksAndMessages(null);
playbackInfo = playbackInfo =
getResetPlaybackInfo( getResetPlaybackInfo(
/* clearPlaylist= */ false, /* clearPlaylist= */ false,
......
...@@ -343,7 +343,6 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -343,7 +343,6 @@ public class SimpleExoPlayer extends BasePlayer
protected final Renderer[] renderers; protected final Renderer[] renderers;
private final ExoPlayerImpl player; private final ExoPlayerImpl player;
private final Handler eventHandler;
private final ComponentListener componentListener; private final ComponentListener componentListener;
private final CopyOnWriteArraySet<com.google.android.exoplayer2.video.VideoListener> private final CopyOnWriteArraySet<com.google.android.exoplayer2.video.VideoListener>
videoListeners; videoListeners;
...@@ -420,8 +419,8 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -420,8 +419,8 @@ public class SimpleExoPlayer extends BasePlayer
* preparations are triggered only when the player starts buffering the media. * 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 * @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. * 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 * @param applicationLooper The {@link Looper} which must be used for all calls to the player and
* used to call listeners on. * which is used to call listeners on.
*/ */
protected SimpleExoPlayer( protected SimpleExoPlayer(
Context context, Context context,
...@@ -433,7 +432,7 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -433,7 +432,7 @@ public class SimpleExoPlayer extends BasePlayer
AnalyticsCollector analyticsCollector, AnalyticsCollector analyticsCollector,
boolean useLazyPreparation, boolean useLazyPreparation,
Clock clock, Clock clock,
Looper looper) { Looper applicationLooper) {
this.bandwidthMeter = bandwidthMeter; this.bandwidthMeter = bandwidthMeter;
this.analyticsCollector = analyticsCollector; this.analyticsCollector = analyticsCollector;
componentListener = new ComponentListener(); componentListener = new ComponentListener();
...@@ -444,7 +443,7 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -444,7 +443,7 @@ public class SimpleExoPlayer extends BasePlayer
deviceListeners = new CopyOnWriteArraySet<>(); deviceListeners = new CopyOnWriteArraySet<>();
videoDebugListeners = new CopyOnWriteArraySet<>(); videoDebugListeners = new CopyOnWriteArraySet<>();
audioDebugListeners = new CopyOnWriteArraySet<>(); audioDebugListeners = new CopyOnWriteArraySet<>();
eventHandler = new Handler(looper); Handler eventHandler = new Handler(applicationLooper);
renderers = renderers =
renderersFactory.createRenderers( renderersFactory.createRenderers(
eventHandler, eventHandler,
...@@ -471,7 +470,7 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -471,7 +470,7 @@ public class SimpleExoPlayer extends BasePlayer
analyticsCollector, analyticsCollector,
useLazyPreparation, useLazyPreparation,
clock, clock,
looper); applicationLooper);
analyticsCollector.setPlayer(player); analyticsCollector.setPlayer(player);
player.addListener(analyticsCollector); player.addListener(analyticsCollector);
player.addListener(componentListener); player.addListener(componentListener);
......
...@@ -62,7 +62,9 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -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 * <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 * 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 { public final class DownloadManager {
...@@ -167,7 +169,7 @@ public final class DownloadManager { ...@@ -167,7 +169,7 @@ public final class DownloadManager {
private final Context context; private final Context context;
private final WritableDownloadIndex downloadIndex; private final WritableDownloadIndex downloadIndex;
private final Handler mainHandler; private final Handler applicationHandler;
private final InternalHandler internalHandler; private final InternalHandler internalHandler;
private final RequirementsWatcher.Listener requirementsListener; private final RequirementsWatcher.Listener requirementsListener;
private final CopyOnWriteArraySet<Listener> listeners; private final CopyOnWriteArraySet<Listener> listeners;
...@@ -224,7 +226,7 @@ public final class DownloadManager { ...@@ -224,7 +226,7 @@ public final class DownloadManager {
@SuppressWarnings("methodref.receiver.bound.invalid") @SuppressWarnings("methodref.receiver.bound.invalid")
Handler mainHandler = Util.createHandler(this::handleMainMessage); Handler mainHandler = Util.createHandler(this::handleMainMessage);
this.mainHandler = mainHandler; this.applicationHandler = mainHandler;
HandlerThread internalThread = new HandlerThread("ExoPlayer:DownloadManager"); HandlerThread internalThread = new HandlerThread("ExoPlayer:DownloadManager");
internalThread.start(); internalThread.start();
internalHandler = internalHandler =
...@@ -250,6 +252,14 @@ public final class DownloadManager { ...@@ -250,6 +252,14 @@ public final class DownloadManager {
.sendToTarget(); .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. */ /** Returns whether the manager has completed initialization. */
public boolean isInitialized() { public boolean isInitialized() {
return initialized; return initialized;
...@@ -488,7 +498,7 @@ public final class DownloadManager { ...@@ -488,7 +498,7 @@ public final class DownloadManager {
// Restore the interrupted status. // Restore the interrupted status.
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
mainHandler.removeCallbacksAndMessages(/* token= */ null); applicationHandler.removeCallbacksAndMessages(/* token= */ null);
// Reset state. // Reset state.
downloads = Collections.emptyList(); downloads = Collections.emptyList();
pendingMessages = 0; pendingMessages = 0;
......
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