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