diff --git a/library/src/main/java/com/google/android/exoplayer/ExoPlayer.java b/library/src/main/java/com/google/android/exoplayer/ExoPlayer.java index 2ebb8b79df..406d353b1f 100644 --- a/library/src/main/java/com/google/android/exoplayer/ExoPlayer.java +++ b/library/src/main/java/com/google/android/exoplayer/ExoPlayer.java @@ -224,13 +224,6 @@ public interface ExoPlayer { */ long UNKNOWN_TIME = -1; - /** - * Gets the {@link Looper} associated with the playback thread. - * - * @return The {@link Looper} associated with the playback thread. - */ - Looper getPlaybackLooper(); - /** * Register a listener to receive events from the player. The listener's methods will be invoked * on the thread that was used to construct the player. diff --git a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImpl.java b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImpl.java index f7820da831..bd95cff11f 100644 --- a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImpl.java +++ b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImpl.java @@ -70,11 +70,6 @@ import java.util.concurrent.CopyOnWriteArraySet; playWhenReady, eventHandler); } - @Override - public Looper getPlaybackLooper() { - return internalPlayer.getPlaybackLooper(); - } - @Override public void addListener(Listener listener) { listeners.add(listener); diff --git a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java index 0342733a11..45baca488b 100644 --- a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java @@ -23,7 +23,6 @@ import com.google.android.exoplayer.util.Util; import android.os.Handler; import android.os.HandlerThread; -import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.SystemClock; @@ -121,10 +120,6 @@ import java.util.concurrent.atomic.AtomicInteger; handler = new Handler(internalPlaybackThread.getLooper(), this); } - public Looper getPlaybackLooper() { - return internalPlaybackThread.getLooper(); - } - public long getCurrentPosition() { return pendingSeekCount.get() > 0 ? lastSeekPositionMs : (positionUs / 1000); } diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java index 875b44deac..cd1aed48b7 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java @@ -28,6 +28,7 @@ import android.media.MediaCodec.CodecException; import android.media.MediaCodec.CryptoException; import android.media.MediaCrypto; import android.os.Handler; +import android.os.Looper; import android.os.SystemClock; import java.nio.ByteBuffer; @@ -290,7 +291,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { new IllegalStateException("Media requires a DrmSessionManager"), getIndex()); } if (!openedDrmSession) { - drmSessionManager.open(format.drmInitData); + drmSessionManager.open(Looper.myLooper(), format.drmInitData); openedDrmSession = true; } int drmSessionState = drmSessionManager.getState(); diff --git a/library/src/main/java/com/google/android/exoplayer/drm/DrmSessionManager.java b/library/src/main/java/com/google/android/exoplayer/drm/DrmSessionManager.java index 481a6ed766..16fa52b730 100644 --- a/library/src/main/java/com/google/android/exoplayer/drm/DrmSessionManager.java +++ b/library/src/main/java/com/google/android/exoplayer/drm/DrmSessionManager.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer.drm; import android.annotation.TargetApi; import android.media.MediaCrypto; +import android.os.Looper; /** * Manages a DRM session. @@ -33,8 +34,8 @@ public interface DrmSessionManager { */ int STATE_CLOSED = 1; /** - * The session is being opened (i.e. {@link #open(DrmInitData)} has been called, but the session - * is not yet open). + * The session is being opened (i.e. {@link #open(Looper, DrmInitData)} has been called, but the + * session is not yet open). */ int STATE_OPENING = 2; /** @@ -49,9 +50,10 @@ public interface DrmSessionManager { /** * Opens the session, possibly asynchronously. * + * @param playbackLooper The looper associated with the media playback thread. * @param drmInitData DRM initialization data. */ - void open(DrmInitData drmInitData); + void open(Looper playbackLooper, DrmInitData drmInitData); /** * Closes the session. diff --git a/library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java b/library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java index 0d64d81320..044e2a95f4 100644 --- a/library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java +++ b/library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer.drm; import com.google.android.exoplayer.C; import com.google.android.exoplayer.drm.DrmInitData.SchemeData; import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil; +import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Util; import android.annotation.SuppressLint; @@ -79,11 +80,13 @@ public class StreamingDrmSessionManager implements DrmSessionManager { private final MediaDrm mediaDrm; private final HashMap optionalKeyRequestParameters; - /* package */ final MediaDrmHandler mediaDrmHandler; /* package */ final MediaDrmCallback callback; - /* package */ final PostResponseHandler postResponseHandler; /* package */ final UUID uuid; + /* package */ MediaDrmHandler mediaDrmHandler; + /* package */ PostResponseHandler postResponseHandler; + + private Looper playbackLooper; private HandlerThread requestHandlerThread; private Handler postRequestHandler; @@ -98,8 +101,6 @@ public class StreamingDrmSessionManager implements DrmSessionManager { /** * Instantiates a new instance using the Widevine scheme. * - * @param playbackLooper The looper associated with the media playback thread. Should usually be - * obtained using {@link com.google.android.exoplayer.ExoPlayer#getPlaybackLooper()}. * @param callback Performs key and provisioning requests. * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null. @@ -108,11 +109,11 @@ public class StreamingDrmSessionManager implements DrmSessionManager { * @param eventListener A listener of events. May be null if delivery of events is not required. * @throws UnsupportedDrmException If the specified DRM scheme is not supported. */ - public static StreamingDrmSessionManager newWidevineInstance(Looper playbackLooper, - MediaDrmCallback callback, HashMap optionalKeyRequestParameters, - Handler eventHandler, EventListener eventListener) throws UnsupportedDrmException { - return new StreamingDrmSessionManager(C.WIDEVINE_UUID, playbackLooper, callback, - optionalKeyRequestParameters, eventHandler, eventListener); + public static StreamingDrmSessionManager newWidevineInstance(MediaDrmCallback callback, + HashMap optionalKeyRequestParameters, Handler eventHandler, + EventListener eventListener) throws UnsupportedDrmException { + return new StreamingDrmSessionManager(C.WIDEVINE_UUID, callback, optionalKeyRequestParameters, + eventHandler, eventListener); } /** @@ -121,8 +122,6 @@ public class StreamingDrmSessionManager implements DrmSessionManager { * Note that PlayReady is unsupported by most Android devices, with the exception of Android TV * devices, which do provide support. * - * @param playbackLooper The looper associated with the media playback thread. Should usually be - * obtained using {@link com.google.android.exoplayer.ExoPlayer#getPlaybackLooper()}. * @param callback Performs key and provisioning requests. * @param customData Optional custom data to include in requests generated by the instance. * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be @@ -130,9 +129,9 @@ public class StreamingDrmSessionManager implements DrmSessionManager { * @param eventListener A listener of events. May be null if delivery of events is not required. * @throws UnsupportedDrmException If the specified DRM scheme is not supported. */ - public static StreamingDrmSessionManager newPlayReadyInstance(Looper playbackLooper, - MediaDrmCallback callback, String customData, Handler eventHandler, - EventListener eventListener) throws UnsupportedDrmException { + public static StreamingDrmSessionManager newPlayReadyInstance(MediaDrmCallback callback, + String customData, Handler eventHandler, EventListener eventListener) + throws UnsupportedDrmException { HashMap optionalKeyRequestParameters; if (!TextUtils.isEmpty(customData)) { optionalKeyRequestParameters = new HashMap<>(); @@ -140,14 +139,12 @@ public class StreamingDrmSessionManager implements DrmSessionManager { } else { optionalKeyRequestParameters = null; } - return new StreamingDrmSessionManager(C.PLAYREADY_UUID, playbackLooper, callback, - optionalKeyRequestParameters, eventHandler, eventListener); + return new StreamingDrmSessionManager(C.PLAYREADY_UUID, callback, optionalKeyRequestParameters, + eventHandler, eventListener); } /** * @param uuid The UUID of the drm scheme. - * @param playbackLooper The looper associated with the media playback thread. Should usually be - * obtained using {@link com.google.android.exoplayer.ExoPlayer#getPlaybackLooper()}. * @param callback Performs key and provisioning requests. * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null. @@ -156,7 +153,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager { * @param eventListener A listener of events. May be null if delivery of events is not required. * @throws UnsupportedDrmException If the specified DRM scheme is not supported. */ - public StreamingDrmSessionManager(UUID uuid, Looper playbackLooper, MediaDrmCallback callback, + public StreamingDrmSessionManager(UUID uuid, MediaDrmCallback callback, HashMap optionalKeyRequestParameters, Handler eventHandler, EventListener eventListener) throws UnsupportedDrmException { this.uuid = uuid; @@ -172,8 +169,6 @@ public class StreamingDrmSessionManager implements DrmSessionManager { throw new UnsupportedDrmException(UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e); } mediaDrm.setOnEventListener(new MediaDrmEventListener()); - mediaDrmHandler = new MediaDrmHandler(playbackLooper); - postResponseHandler = new PostResponseHandler(playbackLooper); state = STATE_CLOSED; } @@ -252,29 +247,34 @@ public class StreamingDrmSessionManager implements DrmSessionManager { } @Override - public void open(DrmInitData drmInitData) { + public void open(Looper playbackLooper, DrmInitData drmInitData) { + Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper); if (++openCount != 1) { return; } - if (postRequestHandler == null) { - requestHandlerThread = new HandlerThread("DrmRequestHandler"); - requestHandlerThread.start(); - postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper()); + + if (this.playbackLooper == null) { + this.playbackLooper = playbackLooper; + mediaDrmHandler = new MediaDrmHandler(playbackLooper); + postResponseHandler = new PostResponseHandler(playbackLooper); } + + requestHandlerThread = new HandlerThread("DrmRequestHandler"); + requestHandlerThread.start(); + postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper()); + + schemeData = drmInitData.get(uuid); if (schemeData == null) { - schemeData = drmInitData.get(uuid); - if (schemeData == null) { - onError(new IllegalStateException("Media does not support uuid: " + uuid)); - return; - } - if (Util.SDK_INT < 21) { - // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. - byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeData.data, C.WIDEVINE_UUID); - if (psshData == null) { - // Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged. - } else { - schemeData = new SchemeData(C.WIDEVINE_UUID, schemeData.mimeType, psshData); - } + onError(new IllegalStateException("Media does not support uuid: " + uuid)); + return; + } + if (Util.SDK_INT < 21) { + // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. + byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeData.data, C.WIDEVINE_UUID); + if (psshData == null) { + // Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged. + } else { + schemeData = new SchemeData(C.WIDEVINE_UUID, schemeData.mimeType, psshData); } } state = STATE_OPENING;