From a43144decf24b9df1e38a6f34feb011b53f1cdbb Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 16 May 2016 13:46:34 -0700 Subject: [PATCH] Don't require playback Looper to build DRM session manager. This is required because in V2 we'll be instantiating DRM session managers before the ExoPlayer instance (and hence we wont have the Looper). This logic will be further cleaned up in later CLs that overhaul DrmSessionManager in more depth. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=122453765 --- .../google/android/exoplayer/ExoPlayer.java | 7 -- .../android/exoplayer/ExoPlayerImpl.java | 5 -- .../exoplayer/ExoPlayerImplInternal.java | 5 -- .../exoplayer/MediaCodecTrackRenderer.java | 3 +- .../exoplayer/drm/DrmSessionManager.java | 8 +- .../drm/StreamingDrmSessionManager.java | 78 +++++++++---------- 6 files changed, 46 insertions(+), 60 deletions(-) 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;