Commit 25f408e6 by tonihei

Move DrmSessionManager initial player setup to its own method.

Currently, DrmSessionManager takes player specific values (= the
playback looper) through (pre)acquireSession calls and requires
the caller to pass in the same values every time.

Instead, we can configure the DrmSessionManager for playback with
a player once before it's being used. We can't simply extend the
prepare() method as prepare may be called before the player is
created to prewarm the DrmSessionManager.

The new method also takes a PlayerId which is bound to the lifetime
of the player similar to the playback looper.

To avoid breakage of custom MediaSources with DRM, we can keep the
old the SampleQueue.createWithDrm method as deprecated.

PiperOrigin-RevId: 410998240
parent e2f0b9a4
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
### dev-v2 (not yet released) ### dev-v2 (not yet released)
* DRM:
* Remove `playbackLooper` from `DrmSessionManager.(pre)acquireSession`.
When a `DrmSessionManager` is used by an app in a custom `MediaSource`,
the `playbackLooper` needs to be passed to `DrmSessionManager.setPlayer`
instead.
### 2.16.1 (2021-11-18) ### 2.16.1 (2021-11-18)
* Core Library: * Core Library:
......
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm;
import static com.google.android.exoplayer2.util.Assertions.checkArgument; import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.media.ResourceBusyException; import android.media.ResourceBusyException;
...@@ -31,6 +32,7 @@ import androidx.annotation.RequiresApi; ...@@ -31,6 +32,7 @@ import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.analytics.PlayerId;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener; import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener;
...@@ -59,7 +61,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -59,7 +61,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* A {@link DrmSessionManager} that supports playbacks using {@link ExoMediaDrm}. * A {@link DrmSessionManager} that supports playbacks using {@link ExoMediaDrm}.
* *
* <p>This implementation supports pre-acquisition of sessions using {@link * <p>This implementation supports pre-acquisition of sessions using {@link
* #preacquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)}. * #preacquireSession(DrmSessionEventListener.EventDispatcher, Format)}.
*/ */
@RequiresApi(18) @RequiresApi(18)
public class DefaultDrmSessionManager implements DrmSessionManager { public class DefaultDrmSessionManager implements DrmSessionManager {
...@@ -419,8 +421,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -419,8 +421,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
/** /**
* Sets the mode, which determines the role of sessions acquired from the instance. This must be * Sets the mode, which determines the role of sessions acquired from the instance. This must be
* called before {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)} * called before {@link #acquireSession(DrmSessionEventListener.EventDispatcher, Format)} is
* is called. * called.
* *
* <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when * <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when
* required. * required.
...@@ -488,12 +490,15 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -488,12 +490,15 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
} }
@Override @Override
public void setPlayer(Looper playbackLooper, PlayerId playerId) {
initPlaybackLooper(playbackLooper);
}
@Override
public DrmSessionReference preacquireSession( public DrmSessionReference preacquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format) {
checkState(prepareCallsCount > 0); checkState(prepareCallsCount > 0);
initPlaybackLooper(playbackLooper); checkStateNotNull(playbackLooper);
PreacquiredSessionReference preacquiredSessionReference = PreacquiredSessionReference preacquiredSessionReference =
new PreacquiredSessionReference(eventDispatcher); new PreacquiredSessionReference(eventDispatcher);
preacquiredSessionReference.acquire(format); preacquiredSessionReference.acquire(format);
...@@ -503,11 +508,9 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -503,11 +508,9 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Override @Override
@Nullable @Nullable
public DrmSession acquireSession( public DrmSession acquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format) {
checkState(prepareCallsCount > 0); checkState(prepareCallsCount > 0);
initPlaybackLooper(playbackLooper); checkStateNotNull(playbackLooper);
return acquireSession( return acquireSession(
playbackLooper, playbackLooper,
eventDispatcher, eventDispatcher,
...@@ -977,7 +980,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -977,7 +980,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
* Constructs an instance. * Constructs an instance.
* *
* @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} passed to {@link * @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} passed to {@link
* #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)}. * #acquireSession(DrmSessionEventListener.EventDispatcher, Format)}.
*/ */
public PreacquiredSessionReference( public PreacquiredSessionReference(
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) { @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) {
......
...@@ -20,6 +20,7 @@ import androidx.annotation.Nullable; ...@@ -20,6 +20,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.analytics.PlayerId;
/** Manages a DRM session. */ /** Manages a DRM session. */
public interface DrmSessionManager { public interface DrmSessionManager {
...@@ -46,11 +47,12 @@ public interface DrmSessionManager { ...@@ -46,11 +47,12 @@ public interface DrmSessionManager {
new DrmSessionManager() { new DrmSessionManager() {
@Override @Override
public void setPlayer(Looper playbackLooper, PlayerId playerId) {}
@Override
@Nullable @Nullable
public DrmSession acquireSession( public DrmSession acquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format) {
if (format.drmInitData == null) { if (format.drmInitData == null) {
return null; return null;
} else { } else {
...@@ -101,24 +103,32 @@ public interface DrmSessionManager { ...@@ -101,24 +103,32 @@ public interface DrmSessionManager {
} }
/** /**
* Sets information about the player using this DRM session manager.
*
* @param playbackLooper The {@link Looper} associated with the player's playback thread.
* @param playerId The {@link PlayerId} of the player.
*/
void setPlayer(Looper playbackLooper, PlayerId playerId);
/**
* Pre-acquires a DRM session for the specified {@link Format}. * Pre-acquires a DRM session for the specified {@link Format}.
* *
* <p>This notifies the manager that a subsequent call to {@link #acquireSession(Looper, * <p>This notifies the manager that a subsequent call to {@link #acquireSession(
* DrmSessionEventListener.EventDispatcher, Format)} with the same {@link Format} is likely, * DrmSessionEventListener.EventDispatcher, Format)} with the same {@link Format} is likely,
* allowing a manager that supports pre-acquisition to get the required {@link DrmSession} ready * allowing a manager that supports pre-acquisition to get the required {@link DrmSession} ready
* in the background. * in the background.
* *
* <p>The caller must call {@link DrmSessionReference#release()} on the returned instance when * <p>The caller must call {@link DrmSessionReference#release()} on the returned instance when
* they no longer require the pre-acquisition (i.e. they know they won't be making a matching call * they no longer require the pre-acquisition (i.e. they know they won't be making a matching call
* to {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)} in the near * to {@link #acquireSession(DrmSessionEventListener.EventDispatcher, Format)} in the near
* future). * future).
* *
* <p>This manager may silently release the underlying session in order to allow another operation * <p>This manager may silently release the underlying session in order to allow another operation
* to complete. This will result in a subsequent call to {@link #acquireSession(Looper, * to complete. This will result in a subsequent call to {@link #acquireSession(
* DrmSessionEventListener.EventDispatcher, Format)} re-initializing a new session, including * DrmSessionEventListener.EventDispatcher, Format)} re-initializing a new session, including
* repeating key loads and other async initialization steps. * repeating key loads and other async initialization steps.
* *
* <p>The caller must separately call {@link #acquireSession(Looper, * <p>The caller must separately call {@link #acquireSession(
* DrmSessionEventListener.EventDispatcher, Format)} in order to obtain a session suitable for * DrmSessionEventListener.EventDispatcher, Format)} in order to obtain a session suitable for
* playback. The pre-acquired {@link DrmSessionReference} and full {@link DrmSession} instances * playback. The pre-acquired {@link DrmSessionReference} and full {@link DrmSession} instances
* are distinct. The caller must release both, and can release the {@link DrmSessionReference} * are distinct. The caller must release both, and can release the {@link DrmSessionReference}
...@@ -129,19 +139,15 @@ public interface DrmSessionManager { ...@@ -129,19 +139,15 @@ public interface DrmSessionManager {
* <p>Implementations that do not support pre-acquisition always return an empty {@link * <p>Implementations that do not support pre-acquisition always return an empty {@link
* DrmSessionReference} instance. * DrmSessionReference} instance.
* *
* @param playbackLooper The looper associated with the media playback thread.
* @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute * @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute
* events, and passed on to {@link * events, and passed on to {@link
* DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}. * DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}.
* @param format The {@link Format} for which to pre-acquire a {@link DrmSession}. * @param format The {@link Format} for which to pre-acquire a {@link DrmSession}.
* @return A releaser for the pre-acquired session. Guaranteed to be non-null even if the matching * @return A releaser for the pre-acquired session. Guaranteed to be non-null even if the matching
* {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)} would * {@link #acquireSession(DrmSessionEventListener.EventDispatcher, Format)} would return null.
* return null.
*/ */
default DrmSessionReference preacquireSession( default DrmSessionReference preacquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format) {
return DrmSessionReference.EMPTY; return DrmSessionReference.EMPTY;
} }
...@@ -158,7 +164,6 @@ public interface DrmSessionManager { ...@@ -158,7 +164,6 @@ public interface DrmSessionManager {
* used to configure secure decoders for playback of clear content periods, which can reduce the * used to configure secure decoders for playback of clear content periods, which can reduce the
* cost of transitioning between clear and encrypted content. * cost of transitioning between clear and encrypted content.
* *
* @param playbackLooper The looper associated with the media playback thread.
* @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute * @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute
* events, and passed on to {@link * events, and passed on to {@link
* DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}. * DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}.
...@@ -167,9 +172,7 @@ public interface DrmSessionManager { ...@@ -167,9 +172,7 @@ public interface DrmSessionManager {
*/ */
@Nullable @Nullable
DrmSession acquireSession( DrmSession acquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format);
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format);
/** /**
* Returns the {@link C.CryptoType} that the DRM session manager will use for a given {@link * Returns the {@link C.CryptoType} that the DRM session manager will use for a given {@link
......
...@@ -23,6 +23,7 @@ import android.util.Pair; ...@@ -23,6 +23,7 @@ import android.util.Pair;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.analytics.PlayerId;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode; import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
...@@ -235,6 +236,7 @@ public final class OfflineLicenseHelper { ...@@ -235,6 +236,7 @@ public final class OfflineLicenseHelper {
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId) public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException { throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId); Assertions.checkNotNull(offlineLicenseKeySetId);
drmSessionManager.setPlayer(handlerThread.getLooper(), PlayerId.UNSET);
drmSessionManager.prepare(); drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
openBlockingKeyRequest( openBlockingKeyRequest(
...@@ -263,6 +265,7 @@ public final class OfflineLicenseHelper { ...@@ -263,6 +265,7 @@ public final class OfflineLicenseHelper {
private byte[] blockingKeyRequest( private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format)
throws DrmSessionException { throws DrmSessionException {
drmSessionManager.setPlayer(handlerThread.getLooper(), PlayerId.UNSET);
drmSessionManager.prepare(); drmSessionManager.prepare();
DrmSession drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, format); DrmSession drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, format);
DrmSessionException error = drmSession.getError(); DrmSessionException error = drmSession.getError();
...@@ -280,8 +283,7 @@ public final class OfflineLicenseHelper { ...@@ -280,8 +283,7 @@ public final class OfflineLicenseHelper {
Assertions.checkNotNull(format.drmInitData); Assertions.checkNotNull(format.drmInitData);
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId); drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
conditionVariable.close(); conditionVariable.close();
DrmSession drmSession = DrmSession drmSession = drmSessionManager.acquireSession(eventDispatcher, format);
drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, format);
// Block current thread until key loading is finished // Block current thread until key loading is finished
conditionVariable.block(); conditionVariable.block();
return Assertions.checkNotNull(drmSession); return Assertions.checkNotNull(drmSession);
......
...@@ -717,11 +717,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -717,11 +717,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
} }
SampleQueue trackOutput = SampleQueue trackOutput =
SampleQueue.createWithDrm( SampleQueue.createWithDrm(allocator, drmSessionManager, drmEventDispatcher);
allocator,
/* playbackLooper= */ handler.getLooper(),
drmSessionManager,
drmEventDispatcher);
trackOutput.setUpstreamFormatChangeListener(this); trackOutput.setUpstreamFormatChangeListener(this);
@NullableType @NullableType
TrackId[] sampleQueueTrackIds = Arrays.copyOf(this.sampleQueueTrackIds, trackCount + 1); TrackId[] sampleQueueTrackIds = Arrays.copyOf(this.sampleQueueTrackIds, trackCount + 1);
......
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.net.Uri; import android.net.Uri;
import android.os.Looper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
...@@ -296,6 +297,8 @@ public final class ProgressiveMediaSource extends BaseMediaSource ...@@ -296,6 +297,8 @@ public final class ProgressiveMediaSource extends BaseMediaSource
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
transferListener = mediaTransferListener; transferListener = mediaTransferListener;
drmSessionManager.prepare(); drmSessionManager.prepare();
drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
notifySourceInfoRefreshed(); notifySourceInfoRefreshed();
} }
......
...@@ -30,11 +30,13 @@ import androidx.annotation.VisibleForTesting; ...@@ -30,11 +30,13 @@ import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.analytics.PlayerId;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer.InsufficientCapacityException; import com.google.android.exoplayer2.decoder.DecoderInputBuffer.InsufficientCapacityException;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionEventListener; import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionEventListener.EventDispatcher;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManager.DrmSessionReference; import com.google.android.exoplayer2.drm.DrmSessionManager.DrmSessionReference;
import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.TrackOutput;
...@@ -71,7 +73,6 @@ public class SampleQueue implements TrackOutput { ...@@ -71,7 +73,6 @@ public class SampleQueue implements TrackOutput {
private final SpannedData<SharedSampleMetadata> sharedSampleMetadata; private final SpannedData<SharedSampleMetadata> sharedSampleMetadata;
@Nullable private final DrmSessionManager drmSessionManager; @Nullable private final DrmSessionManager drmSessionManager;
@Nullable private final DrmSessionEventListener.EventDispatcher drmEventDispatcher; @Nullable private final DrmSessionEventListener.EventDispatcher drmEventDispatcher;
@Nullable private final Looper playbackLooper;
@Nullable private UpstreamFormatChangedListener upstreamFormatChangeListener; @Nullable private UpstreamFormatChangedListener upstreamFormatChangeListener;
@Nullable private Format downstreamFormat; @Nullable private Format downstreamFormat;
...@@ -113,10 +114,7 @@ public class SampleQueue implements TrackOutput { ...@@ -113,10 +114,7 @@ public class SampleQueue implements TrackOutput {
*/ */
public static SampleQueue createWithoutDrm(Allocator allocator) { public static SampleQueue createWithoutDrm(Allocator allocator) {
return new SampleQueue( return new SampleQueue(
allocator, allocator, /* drmSessionManager= */ null, /* drmEventDispatcher= */ null);
/* playbackLooper= */ null,
/* drmSessionManager= */ null,
/* drmEventDispatcher= */ null);
} }
/** /**
...@@ -126,7 +124,6 @@ public class SampleQueue implements TrackOutput { ...@@ -126,7 +124,6 @@ public class SampleQueue implements TrackOutput {
* keys needed to decrypt it. * keys needed to decrypt it.
* *
* @param allocator An {@link Allocator} from which allocations for sample data can be obtained. * @param allocator An {@link Allocator} from which allocations for sample data can be obtained.
* @param playbackLooper The looper associated with the media playback thread.
* @param drmSessionManager The {@link DrmSessionManager} to obtain {@link DrmSession DrmSessions} * @param drmSessionManager The {@link DrmSessionManager} to obtain {@link DrmSession DrmSessions}
* from. The created instance does not take ownership of this {@link DrmSessionManager}. * from. The created instance does not take ownership of this {@link DrmSessionManager}.
* @param drmEventDispatcher A {@link DrmSessionEventListener.EventDispatcher} to notify of events * @param drmEventDispatcher A {@link DrmSessionEventListener.EventDispatcher} to notify of events
...@@ -134,22 +131,36 @@ public class SampleQueue implements TrackOutput { ...@@ -134,22 +131,36 @@ public class SampleQueue implements TrackOutput {
*/ */
public static SampleQueue createWithDrm( public static SampleQueue createWithDrm(
Allocator allocator, Allocator allocator,
DrmSessionManager drmSessionManager,
DrmSessionEventListener.EventDispatcher drmEventDispatcher) {
return new SampleQueue(
allocator,
Assertions.checkNotNull(drmSessionManager),
Assertions.checkNotNull(drmEventDispatcher));
}
/**
* @deprecated Use {@link #createWithDrm(Allocator, DrmSessionManager, EventDispatcher)} instead.
* The {@code playbackLooper} should be configured on the {@link DrmSessionManager} with
* {@link DrmSessionManager#setPlayer(Looper, PlayerId)}.
*/
@Deprecated
public static SampleQueue createWithDrm(
Allocator allocator,
Looper playbackLooper, Looper playbackLooper,
DrmSessionManager drmSessionManager, DrmSessionManager drmSessionManager,
DrmSessionEventListener.EventDispatcher drmEventDispatcher) { DrmSessionEventListener.EventDispatcher drmEventDispatcher) {
drmSessionManager.setPlayer(playbackLooper, PlayerId.UNSET);
return new SampleQueue( return new SampleQueue(
allocator, allocator,
Assertions.checkNotNull(playbackLooper),
Assertions.checkNotNull(drmSessionManager), Assertions.checkNotNull(drmSessionManager),
Assertions.checkNotNull(drmEventDispatcher)); Assertions.checkNotNull(drmEventDispatcher));
} }
protected SampleQueue( protected SampleQueue(
Allocator allocator, Allocator allocator,
@Nullable Looper playbackLooper,
@Nullable DrmSessionManager drmSessionManager, @Nullable DrmSessionManager drmSessionManager,
@Nullable DrmSessionEventListener.EventDispatcher drmEventDispatcher) { @Nullable DrmSessionEventListener.EventDispatcher drmEventDispatcher) {
this.playbackLooper = playbackLooper;
this.drmSessionManager = drmSessionManager; this.drmSessionManager = drmSessionManager;
this.drmEventDispatcher = drmEventDispatcher; this.drmEventDispatcher = drmEventDispatcher;
sampleDataQueue = new SampleDataQueue(allocator); sampleDataQueue = new SampleDataQueue(allocator);
...@@ -803,8 +814,7 @@ public class SampleQueue implements TrackOutput { ...@@ -803,8 +814,7 @@ public class SampleQueue implements TrackOutput {
|| !sharedSampleMetadata.getEndValue().format.equals(upstreamFormat)) { || !sharedSampleMetadata.getEndValue().format.equals(upstreamFormat)) {
DrmSessionReference drmSessionReference = DrmSessionReference drmSessionReference =
drmSessionManager != null drmSessionManager != null
? drmSessionManager.preacquireSession( ? drmSessionManager.preacquireSession(drmEventDispatcher, upstreamFormat)
checkNotNull(playbackLooper), drmEventDispatcher, upstreamFormat)
: DrmSessionReference.EMPTY; : DrmSessionReference.EMPTY;
sharedSampleMetadata.appendSpan( sharedSampleMetadata.appendSpan(
...@@ -913,9 +923,7 @@ public class SampleQueue implements TrackOutput { ...@@ -913,9 +923,7 @@ public class SampleQueue implements TrackOutput {
// Ensure we acquire the new session before releasing the previous one in case the same session // Ensure we acquire the new session before releasing the previous one in case the same session
// is being used for both DrmInitData. // is being used for both DrmInitData.
@Nullable DrmSession previousSession = currentDrmSession; @Nullable DrmSession previousSession = currentDrmSession;
currentDrmSession = currentDrmSession = drmSessionManager.acquireSession(drmEventDispatcher, newFormat);
drmSessionManager.acquireSession(
Assertions.checkNotNull(playbackLooper), drmEventDispatcher, newFormat);
outputFormatHolder.drmSession = currentDrmSession; outputFormatHolder.drmSession = currentDrmSession;
if (previousSession != null) { if (previousSession != null) {
......
...@@ -19,7 +19,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull; ...@@ -19,7 +19,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
import android.os.Looper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
...@@ -144,11 +143,7 @@ public class ChunkSampleStream<T extends ChunkSource> ...@@ -144,11 +143,7 @@ public class ChunkSampleStream<T extends ChunkSource>
SampleQueue[] sampleQueues = new SampleQueue[1 + embeddedTrackCount]; SampleQueue[] sampleQueues = new SampleQueue[1 + embeddedTrackCount];
primarySampleQueue = primarySampleQueue =
SampleQueue.createWithDrm( SampleQueue.createWithDrm(allocator, drmSessionManager, drmEventDispatcher);
allocator,
/* playbackLooper= */ checkNotNull(Looper.myLooper()),
drmSessionManager,
drmEventDispatcher);
trackTypes[0] = primaryTrackType; trackTypes[0] = primaryTrackType;
sampleQueues[0] = primarySampleQueue; sampleQueues[0] = primarySampleQueue;
......
...@@ -36,6 +36,7 @@ import com.google.android.exoplayer2.C; ...@@ -36,6 +36,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.analytics.PlayerId;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
...@@ -46,7 +47,6 @@ import com.google.android.exoplayer2.testutil.FakeCryptoConfig; ...@@ -46,7 +47,6 @@ import com.google.android.exoplayer2.testutil.FakeCryptoConfig;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
...@@ -146,12 +146,7 @@ public final class SampleQueueTest { ...@@ -146,12 +146,7 @@ public final class SampleQueueTest {
mockDrmSession = Mockito.mock(DrmSession.class); mockDrmSession = Mockito.mock(DrmSession.class);
mockDrmSessionManager = new MockDrmSessionManager(mockDrmSession); mockDrmSessionManager = new MockDrmSessionManager(mockDrmSession);
eventDispatcher = new DrmSessionEventListener.EventDispatcher(); eventDispatcher = new DrmSessionEventListener.EventDispatcher();
sampleQueue = sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
new SampleQueue(
allocator,
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
mockDrmSessionManager,
eventDispatcher);
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
} }
...@@ -424,12 +419,7 @@ public final class SampleQueueTest { ...@@ -424,12 +419,7 @@ public final class SampleQueueTest {
public void isReadyReturnsTrueForClearSampleAndPlayClearSamplesWithoutKeysIsTrue() { public void isReadyReturnsTrueForClearSampleAndPlayClearSamplesWithoutKeysIsTrue() {
when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true); when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true);
// We recreate the queue to ensure the mock DRM session manager flags are taken into account. // We recreate the queue to ensure the mock DRM session manager flags are taken into account.
sampleQueue = sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
new SampleQueue(
allocator,
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
mockDrmSessionManager,
eventDispatcher);
writeTestDataWithEncryptedSections(); writeTestDataWithEncryptedSections();
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue(); assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue();
} }
...@@ -574,12 +564,7 @@ public final class SampleQueueTest { ...@@ -574,12 +564,7 @@ public final class SampleQueueTest {
public void allowPlayClearSamplesWithoutKeysReadsClearSamples() { public void allowPlayClearSamplesWithoutKeysReadsClearSamples() {
when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true); when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true);
// We recreate the queue to ensure the mock DRM session manager flags are taken into account. // We recreate the queue to ensure the mock DRM session manager flags are taken into account.
sampleQueue = sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
new SampleQueue(
allocator,
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
mockDrmSessionManager,
eventDispatcher);
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED); when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
writeTestDataWithEncryptedSections(); writeTestDataWithEncryptedSections();
...@@ -1246,11 +1231,7 @@ public final class SampleQueueTest { ...@@ -1246,11 +1231,7 @@ public final class SampleQueueTest {
public void adjustUpstreamFormat() { public void adjustUpstreamFormat() {
String label = "label"; String label = "label";
sampleQueue = sampleQueue =
new SampleQueue( new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
allocator,
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
mockDrmSessionManager,
eventDispatcher) {
@Override @Override
public Format getAdjustedUpstreamFormat(Format format) { public Format getAdjustedUpstreamFormat(Format format) {
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label)); return super.getAdjustedUpstreamFormat(copyWithLabel(format, label));
...@@ -1266,11 +1247,7 @@ public final class SampleQueueTest { ...@@ -1266,11 +1247,7 @@ public final class SampleQueueTest {
public void invalidateUpstreamFormatAdjustment() { public void invalidateUpstreamFormatAdjustment() {
AtomicReference<String> label = new AtomicReference<>("label1"); AtomicReference<String> label = new AtomicReference<>("label1");
sampleQueue = sampleQueue =
new SampleQueue( new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
allocator,
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
mockDrmSessionManager,
eventDispatcher) {
@Override @Override
public Format getAdjustedUpstreamFormat(Format format) { public Format getAdjustedUpstreamFormat(Format format) {
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label.get())); return super.getAdjustedUpstreamFormat(copyWithLabel(format, label.get()));
...@@ -1771,11 +1748,12 @@ public final class SampleQueueTest { ...@@ -1771,11 +1748,12 @@ public final class SampleQueueTest {
} }
@Override @Override
public void setPlayer(Looper playbackLooper, PlayerId playerId) {}
@Override
@Nullable @Nullable
public DrmSession acquireSession( public DrmSession acquireSession(
Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
Format format) {
return format.drmInitData != null ? mockDrmSession : mockPlaceholderDrmSession; return format.drmInitData != null ? mockDrmSession : mockPlaceholderDrmSession;
} }
......
...@@ -22,6 +22,7 @@ import static java.lang.Math.min; ...@@ -22,6 +22,7 @@ import static java.lang.Math.min;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
...@@ -559,6 +560,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -559,6 +560,7 @@ public final class DashMediaSource extends BaseMediaSource {
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare(); drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId());
if (sideloadedManifest) { if (sideloadedManifest) {
processManifest(false); processManifest(false);
} else { } else {
......
...@@ -19,6 +19,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull; ...@@ -19,6 +19,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static java.lang.annotation.RetentionPolicy.SOURCE; import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.net.Uri; import android.net.Uri;
import android.os.Looper;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -466,6 +467,8 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -466,6 +467,8 @@ public final class HlsMediaSource extends BaseMediaSource
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare(); drmSessionManager.prepare();
drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
MediaSourceEventListener.EventDispatcher eventDispatcher = MediaSourceEventListener.EventDispatcher eventDispatcher =
createEventDispatcher(/* mediaPeriodId= */ null); createEventDispatcher(/* mediaPeriodId= */ null);
playlistTracker.start( playlistTracker.start(
......
...@@ -23,7 +23,6 @@ import static java.lang.Math.min; ...@@ -23,7 +23,6 @@ import static java.lang.Math.min;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -1100,12 +1099,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -1100,12 +1099,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
boolean isAudioVideo = type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO; boolean isAudioVideo = type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO;
HlsSampleQueue sampleQueue = HlsSampleQueue sampleQueue =
new HlsSampleQueue( new HlsSampleQueue(allocator, drmSessionManager, drmEventDispatcher, overridingDrmInitData);
allocator,
/* playbackLooper= */ handler.getLooper(),
drmSessionManager,
drmEventDispatcher,
overridingDrmInitData);
sampleQueue.setStartTimeUs(lastSeekPositionUs); sampleQueue.setStartTimeUs(lastSeekPositionUs);
if (isAudioVideo) { if (isAudioVideo) {
sampleQueue.setDrmInitData(drmInitData); sampleQueue.setDrmInitData(drmInitData);
...@@ -1639,11 +1633,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -1639,11 +1633,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private HlsSampleQueue( private HlsSampleQueue(
Allocator allocator, Allocator allocator,
Looper playbackLooper,
DrmSessionManager drmSessionManager, DrmSessionManager drmSessionManager,
DrmSessionEventListener.EventDispatcher eventDispatcher, DrmSessionEventListener.EventDispatcher eventDispatcher,
Map<String, DrmInitData> overridingDrmInitData) { Map<String, DrmInitData> overridingDrmInitData) {
super(allocator, playbackLooper, drmSessionManager, eventDispatcher); super(allocator, drmSessionManager, eventDispatcher);
this.overridingDrmInitData = overridingDrmInitData; this.overridingDrmInitData = overridingDrmInitData;
} }
......
...@@ -21,6 +21,7 @@ import static java.lang.Math.min; ...@@ -21,6 +21,7 @@ import static java.lang.Math.min;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -436,6 +437,7 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -436,6 +437,7 @@ public final class SsMediaSource extends BaseMediaSource
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare(); drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId());
if (sideloadedManifest) { if (sideloadedManifest) {
manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy(); manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy();
processManifest(); processManifest();
......
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
*/ */
package com.google.android.exoplayer2.testutil; package com.google.android.exoplayer2.testutil;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull; import static com.google.android.exoplayer2.util.Util.castNonNull;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -212,6 +214,8 @@ public class FakeMediaSource extends BaseMediaSource { ...@@ -212,6 +214,8 @@ public class FakeMediaSource extends BaseMediaSource {
assertThat(preparedSource).isFalse(); assertThat(preparedSource).isFalse();
transferListener = mediaTransferListener; transferListener = mediaTransferListener;
drmSessionManager.prepare(); drmSessionManager.prepare();
drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
preparedSource = true; preparedSource = true;
releasedSource = false; releasedSource = false;
sourceInfoRefreshHandler = Util.createHandlerForCurrentLooper(); sourceInfoRefreshHandler = Util.createHandlerForCurrentLooper();
......
...@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.testutil; ...@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.testutil;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.os.Looper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
...@@ -136,12 +135,7 @@ public class FakeSampleStream implements SampleStream { ...@@ -136,12 +135,7 @@ public class FakeSampleStream implements SampleStream {
DrmSessionEventListener.EventDispatcher drmEventDispatcher, DrmSessionEventListener.EventDispatcher drmEventDispatcher,
Format initialFormat, Format initialFormat,
List<FakeSampleStreamItem> fakeSampleStreamItems) { List<FakeSampleStreamItem> fakeSampleStreamItems) {
this.sampleQueue = this.sampleQueue = SampleQueue.createWithDrm(allocator, drmSessionManager, drmEventDispatcher);
SampleQueue.createWithDrm(
allocator,
/* playbackLooper= */ checkNotNull(Looper.myLooper()),
drmSessionManager,
drmEventDispatcher);
this.mediaSourceEventDispatcher = mediaSourceEventDispatcher; this.mediaSourceEventDispatcher = mediaSourceEventDispatcher;
this.sampleStreamItems = new ArrayList<>(); this.sampleStreamItems = new ArrayList<>();
sampleStreamItems.add(FakeSampleStreamItem.format(initialFormat)); sampleStreamItems.add(FakeSampleStreamItem.format(initialFormat));
......
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