Remove DrmSessionManager.acquirePlaceholderSession
In order to acquire a placeholder session, clients can call acquireSession with a format with a null drmInitData. PiperOrigin-RevId: 327220249
This commit is contained in:
parent
be98509e03
commit
41e6577dca
@ -409,7 +409,7 @@ 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(Looper, DrmSessionEventListener.EventDispatcher, Format)}
|
||||||
* or {@link #acquirePlaceholderSession} is called.
|
* is 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.
|
||||||
@ -469,34 +469,6 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public DrmSession acquirePlaceholderSession(Looper playbackLooper, int trackType) {
|
|
||||||
initPlaybackLooper(playbackLooper);
|
|
||||||
ExoMediaDrm exoMediaDrm = Assertions.checkNotNull(this.exoMediaDrm);
|
|
||||||
boolean avoidPlaceholderDrmSessions =
|
|
||||||
FrameworkMediaCrypto.class.equals(exoMediaDrm.getExoMediaCryptoType())
|
|
||||||
&& FrameworkMediaCrypto.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC;
|
|
||||||
// Avoid attaching a session to sparse formats.
|
|
||||||
if (avoidPlaceholderDrmSessions
|
|
||||||
|| Util.linearSearch(useDrmSessionsForClearContentTrackTypes, trackType) == C.INDEX_UNSET
|
|
||||||
|| exoMediaDrm.getExoMediaCryptoType() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
maybeCreateMediaDrmHandler(playbackLooper);
|
|
||||||
if (placeholderDrmSession == null) {
|
|
||||||
DefaultDrmSession placeholderDrmSession =
|
|
||||||
createAndAcquireSessionWithRetry(
|
|
||||||
/* schemeDatas= */ ImmutableList.of(),
|
|
||||||
/* isPlaceholderSession= */ true,
|
|
||||||
/* eventDispatcher= */ null);
|
|
||||||
sessions.add(placeholderDrmSession);
|
|
||||||
this.placeholderDrmSession = placeholderDrmSession;
|
|
||||||
} else {
|
|
||||||
placeholderDrmSession.acquire(/* eventDispatcher= */ null);
|
|
||||||
}
|
|
||||||
return placeholderDrmSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DrmSession acquireSession(
|
public DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
@ -504,6 +476,11 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
initPlaybackLooper(playbackLooper);
|
initPlaybackLooper(playbackLooper);
|
||||||
maybeCreateMediaDrmHandler(playbackLooper);
|
maybeCreateMediaDrmHandler(playbackLooper);
|
||||||
|
|
||||||
|
if (format.drmInitData == null) {
|
||||||
|
// Content is not encrypted.
|
||||||
|
return maybeAcquirePlaceholderSession(MimeTypes.getTrackType(format.sampleMimeType));
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable List<SchemeData> schemeDatas = null;
|
@Nullable List<SchemeData> schemeDatas = null;
|
||||||
if (offlineLicenseKeySetId == null) {
|
if (offlineLicenseKeySetId == null) {
|
||||||
schemeDatas = getSchemeDatas(Assertions.checkNotNull(format.drmInitData), uuid, false);
|
schemeDatas = getSchemeDatas(Assertions.checkNotNull(format.drmInitData), uuid, false);
|
||||||
@ -565,6 +542,32 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private DrmSession maybeAcquirePlaceholderSession(int trackType) {
|
||||||
|
ExoMediaDrm exoMediaDrm = Assertions.checkNotNull(this.exoMediaDrm);
|
||||||
|
boolean avoidPlaceholderDrmSessions =
|
||||||
|
FrameworkMediaCrypto.class.equals(exoMediaDrm.getExoMediaCryptoType())
|
||||||
|
&& FrameworkMediaCrypto.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC;
|
||||||
|
// Avoid attaching a session to sparse formats.
|
||||||
|
if (avoidPlaceholderDrmSessions
|
||||||
|
|| Util.linearSearch(useDrmSessionsForClearContentTrackTypes, trackType) == C.INDEX_UNSET
|
||||||
|
|| exoMediaDrm.getExoMediaCryptoType() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (placeholderDrmSession == null) {
|
||||||
|
DefaultDrmSession placeholderDrmSession =
|
||||||
|
createAndAcquireSessionWithRetry(
|
||||||
|
/* schemeDatas= */ ImmutableList.of(),
|
||||||
|
/* isPlaceholderSession= */ true,
|
||||||
|
/* eventDispatcher= */ null);
|
||||||
|
sessions.add(placeholderDrmSession);
|
||||||
|
this.placeholderDrmSession = placeholderDrmSession;
|
||||||
|
} else {
|
||||||
|
placeholderDrmSession.acquire(/* eventDispatcher= */ null);
|
||||||
|
}
|
||||||
|
return placeholderDrmSession;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean canAcquireSession(DrmInitData drmInitData) {
|
private boolean canAcquireSession(DrmInitData drmInitData) {
|
||||||
if (offlineLicenseKeySetId != null) {
|
if (offlineLicenseKeySetId != null) {
|
||||||
// An offline license can be restored so a session can always be acquired.
|
// An offline license can be restored so a session can always be acquired.
|
||||||
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.drm;
|
|||||||
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
|
|
||||||
/** Manages a DRM session. */
|
/** Manages a DRM session. */
|
||||||
@ -33,13 +32,19 @@ public interface DrmSessionManager {
|
|||||||
new DrmSessionManager() {
|
new DrmSessionManager() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public DrmSession acquireSession(
|
public DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
Format format) {
|
Format format) {
|
||||||
return new ErrorStateDrmSession(
|
if (format.drmInitData == null) {
|
||||||
new DrmSession.DrmSessionException(
|
return null;
|
||||||
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
} else {
|
||||||
|
return new ErrorStateDrmSession(
|
||||||
|
new DrmSession.DrmSessionException(
|
||||||
|
new UnsupportedDrmException(
|
||||||
|
UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,39 +69,27 @@ public interface DrmSessionManager {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a {@link DrmSession} that does not execute key requests, with an incremented reference
|
|
||||||
* count. When the caller no longer needs to use the instance, it must call {@link
|
|
||||||
* DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count.
|
|
||||||
*
|
|
||||||
* <p>Placeholder {@link DrmSession DrmSessions} may be used to configure secure decoders for
|
|
||||||
* playback of clear content periods. This can reduce the cost of transitioning between clear and
|
|
||||||
* encrypted content periods.
|
|
||||||
*
|
|
||||||
* @param playbackLooper The looper associated with the media playback thread.
|
|
||||||
* @param trackType The type of the track to acquire a placeholder session for. Must be one of the
|
|
||||||
* {@link C}{@code .TRACK_TYPE_*} constants.
|
|
||||||
* @return The placeholder DRM session, or null if this DRM session manager does not support
|
|
||||||
* placeholder sessions.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default DrmSession acquirePlaceholderSession(Looper playbackLooper, int trackType) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link DrmSession} for the specified {@link Format}, with an incremented reference
|
* Returns a {@link DrmSession} for the specified {@link Format}, with an incremented reference
|
||||||
* count. When the caller no longer needs to use the instance, it must call {@link
|
* count. May return null if the {@link Format#drmInitData} is null and the DRM session manager is
|
||||||
|
* not configured to attach a {@link DrmSession} to clear content. When the caller no longer needs
|
||||||
|
* to use a returned {@link DrmSession}, it must call {@link
|
||||||
* DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count.
|
* DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count.
|
||||||
*
|
*
|
||||||
|
* <p>If the provided {@link Format} contains a null {@link Format#drmInitData}, the returned
|
||||||
|
* {@link DrmSession} (if not null) will be a placeholder session which does not execute key
|
||||||
|
* requests, and cannot be used to handle encrypted content. However, a placeholder session may be
|
||||||
|
* 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 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 acquire a {@link DrmSession}. Must contain a
|
* @param format The {@link Format} for which to acquire a {@link DrmSession}.
|
||||||
* non-null {@link Format#drmInitData}.
|
* @return The DRM session. May be null if the given {@link Format#drmInitData} is null.
|
||||||
* @return The DRM session.
|
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
DrmSession acquireSession(
|
DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
@ -105,16 +98,16 @@ public interface DrmSessionManager {
|
|||||||
/**
|
/**
|
||||||
* Returns the {@link ExoMediaCrypto} type associated to sessions acquired for the given {@link
|
* Returns the {@link ExoMediaCrypto} type associated to sessions acquired for the given {@link
|
||||||
* Format}. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does not
|
* Format}. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does not
|
||||||
* support any of the DRM schemes defined in the given {@link Format}. If the {@link Format}
|
* support any of the DRM schemes defined in the given {@link Format}. Returns null if {@link
|
||||||
* describes unencrypted content, returns an {@link ExoMediaCrypto} type if this DRM session
|
* Format#drmInitData} is null and {@link #acquireSession} would return null for the given {@link
|
||||||
* manager would associate a {@link #acquirePlaceholderSession placeholder session} to the given
|
* Format}.
|
||||||
* {@link Format}, or null otherwise.
|
|
||||||
*
|
*
|
||||||
* @param format The {@link Format} for which to return the {@link ExoMediaCrypto} type.
|
* @param format The {@link Format} for which to return the {@link ExoMediaCrypto} type.
|
||||||
* @return The {@link ExoMediaCrypto} type associated to sessions acquired using the given
|
* @return The {@link ExoMediaCrypto} type associated to sessions acquired using the given {@link
|
||||||
* parameters, or the {@link UnsupportedMediaCrypto} type if the provided {@code drmInitData}
|
* Format}, or {@link UnsupportedMediaCrypto} if this DRM session manager does not support any
|
||||||
* is not supported, or {@code null} if {@code drmInitData} is null and no DRM session will be
|
* of the DRM schemes defined in the given {@link Format}. May be null if {@link
|
||||||
* associated to the given {@code trackType}.
|
* Format#drmInitData} is null and {@link #acquireSession} would return null for the given
|
||||||
|
* {@link Format}.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
Class<? extends ExoMediaCrypto> getExoMediaCryptoType(Format format);
|
Class<? extends ExoMediaCrypto> getExoMediaCryptoType(Format format);
|
||||||
|
@ -184,7 +184,8 @@ public final class OfflineLicenseHelper {
|
|||||||
/**
|
/**
|
||||||
* Downloads an offline license.
|
* Downloads an offline license.
|
||||||
*
|
*
|
||||||
* @param format The {@link Format} of the content whose license is to be downloaded.
|
* @param format The {@link Format} of the content whose license is to be downloaded. Must contain
|
||||||
|
* a non-null {@link Format#drmInitData}.
|
||||||
* @return The key set id for the downloaded license.
|
* @return The key set id for the downloaded license.
|
||||||
* @throws DrmSessionException Thrown when a DRM session error occurs.
|
* @throws DrmSessionException Thrown when a DRM session error occurs.
|
||||||
*/
|
*/
|
||||||
@ -278,13 +279,14 @@ public final class OfflineLicenseHelper {
|
|||||||
|
|
||||||
private DrmSession openBlockingKeyRequest(
|
private DrmSession openBlockingKeyRequest(
|
||||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) {
|
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) {
|
||||||
|
Assertions.checkNotNull(format.drmInitData);
|
||||||
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
||||||
conditionVariable.close();
|
conditionVariable.close();
|
||||||
DrmSession drmSession =
|
DrmSession drmSession =
|
||||||
drmSessionManager.acquireSession(handlerThread.getLooper(), 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 drmSession;
|
return Assertions.checkNotNull(drmSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -327,13 +327,7 @@ public class SampleQueue implements TrackOutput {
|
|||||||
* Attempts to read from the queue.
|
* Attempts to read from the queue.
|
||||||
*
|
*
|
||||||
* <p>{@link Format Formats} read from this method may be associated to a {@link DrmSession}
|
* <p>{@link Format Formats} read from this method may be associated to a {@link DrmSession}
|
||||||
* through {@link FormatHolder#drmSession}, which is populated in two scenarios:
|
* through {@link FormatHolder#drmSession}.
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>The {@link Format} has a non-null {@link Format#drmInitData}.
|
|
||||||
* <li>The {@link DrmSessionManager} provides placeholder sessions for this queue's track type.
|
|
||||||
* See {@link DrmSessionManager#acquirePlaceholderSession(Looper, int)}.
|
|
||||||
* </ul>
|
|
||||||
*
|
*
|
||||||
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
|
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
|
||||||
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
|
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
|
||||||
@ -842,10 +836,7 @@ public class SampleQueue implements TrackOutput {
|
|||||||
// is being used for both DrmInitData.
|
// is being used for both DrmInitData.
|
||||||
@Nullable DrmSession previousSession = currentDrmSession;
|
@Nullable DrmSession previousSession = currentDrmSession;
|
||||||
currentDrmSession =
|
currentDrmSession =
|
||||||
newDrmInitData != null
|
drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat);
|
||||||
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat)
|
|
||||||
: drmSessionManager.acquirePlaceholderSession(
|
|
||||||
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
|
||||||
outputFormatHolder.drmSession = currentDrmSession;
|
outputFormatHolder.drmSession = currentDrmSession;
|
||||||
|
|
||||||
if (previousSession != null) {
|
if (previousSession != null) {
|
||||||
|
@ -38,6 +38,7 @@ 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.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||||
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;
|
||||||
@ -54,7 +55,6 @@ import org.junit.Assert;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentMatchers;
|
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
/** Test for {@link SampleQueue}. */
|
/** Test for {@link SampleQueue}. */
|
||||||
@ -69,6 +69,8 @@ public final class SampleQueueTest {
|
|||||||
private static final Format FORMAT_SPLICED = buildFormat(/* id= */ "spliced");
|
private static final Format FORMAT_SPLICED = buildFormat(/* id= */ "spliced");
|
||||||
private static final Format FORMAT_ENCRYPTED =
|
private static final Format FORMAT_ENCRYPTED =
|
||||||
new Format.Builder().setId(/* id= */ "encrypted").setDrmInitData(new DrmInitData()).build();
|
new Format.Builder().setId(/* id= */ "encrypted").setDrmInitData(new DrmInitData()).build();
|
||||||
|
private static final Format FORMAT_ENCRYPTED_WITH_EXO_MEDIA_CRYPTO_TYPE =
|
||||||
|
FORMAT_ENCRYPTED.copyWithExoMediaCryptoType(MockExoMediaCrypto.class);
|
||||||
private static final byte[] DATA = TestUtil.buildTestData(ALLOCATION_SIZE * 10);
|
private static final byte[] DATA = TestUtil.buildTestData(ALLOCATION_SIZE * 10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -128,7 +130,7 @@ public final class SampleQueueTest {
|
|||||||
new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, new byte[16], 0, 0);
|
new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, new byte[16], 0, 0);
|
||||||
|
|
||||||
private Allocator allocator;
|
private Allocator allocator;
|
||||||
private DrmSessionManager mockDrmSessionManager;
|
private MockDrmSessionManager mockDrmSessionManager;
|
||||||
private DrmSession mockDrmSession;
|
private DrmSession mockDrmSession;
|
||||||
private DrmSessionEventListener.EventDispatcher eventDispatcher;
|
private DrmSessionEventListener.EventDispatcher eventDispatcher;
|
||||||
private SampleQueue sampleQueue;
|
private SampleQueue sampleQueue;
|
||||||
@ -138,11 +140,8 @@ public final class SampleQueueTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
allocator = new DefaultAllocator(false, ALLOCATION_SIZE);
|
allocator = new DefaultAllocator(false, ALLOCATION_SIZE);
|
||||||
mockDrmSessionManager = Mockito.mock(DrmSessionManager.class);
|
|
||||||
mockDrmSession = Mockito.mock(DrmSession.class);
|
mockDrmSession = Mockito.mock(DrmSession.class);
|
||||||
when(mockDrmSessionManager.acquireSession(
|
mockDrmSessionManager = new MockDrmSessionManager(mockDrmSession);
|
||||||
ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any()))
|
|
||||||
.thenReturn(mockDrmSession);
|
|
||||||
eventDispatcher = new DrmSessionEventListener.EventDispatcher();
|
eventDispatcher = new DrmSessionEventListener.EventDispatcher();
|
||||||
sampleQueue =
|
sampleQueue =
|
||||||
new SampleQueue(
|
new SampleQueue(
|
||||||
@ -399,7 +398,7 @@ public final class SampleQueueTest {
|
|||||||
@Test
|
@Test
|
||||||
public void isReadyReturnsTrueForValidDrmSession() {
|
public void isReadyReturnsTrueForValidDrmSession() {
|
||||||
writeTestDataWithEncryptedSections();
|
writeTestDataWithEncryptedSections();
|
||||||
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED);
|
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED_WITH_EXO_MEDIA_CRYPTO_TYPE);
|
||||||
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isFalse();
|
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isFalse();
|
||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue();
|
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue();
|
||||||
@ -424,7 +423,7 @@ public final class SampleQueueTest {
|
|||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
||||||
writeTestDataWithEncryptedSections();
|
writeTestDataWithEncryptedSections();
|
||||||
|
|
||||||
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED);
|
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED_WITH_EXO_MEDIA_CRYPTO_TYPE);
|
||||||
assertReadNothing(/* formatRequired= */ false);
|
assertReadNothing(/* formatRequired= */ false);
|
||||||
assertThat(inputBuffer.waitingForKeys).isTrue();
|
assertThat(inputBuffer.waitingForKeys).isTrue();
|
||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
@ -464,9 +463,7 @@ public final class SampleQueueTest {
|
|||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
|
DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
|
||||||
when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
when(mockDrmSessionManager.acquirePlaceholderSession(
|
mockDrmSessionManager.mockPlaceholderDrmSession = mockPlaceholderDrmSession;
|
||||||
ArgumentMatchers.any(), ArgumentMatchers.anyInt()))
|
|
||||||
.thenReturn(mockPlaceholderDrmSession);
|
|
||||||
writeTestDataWithEncryptedSections();
|
writeTestDataWithEncryptedSections();
|
||||||
|
|
||||||
int result =
|
int result =
|
||||||
@ -497,9 +494,7 @@ public final class SampleQueueTest {
|
|||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
|
DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
|
||||||
when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
when(mockDrmSessionManager.acquirePlaceholderSession(
|
mockDrmSessionManager.mockPlaceholderDrmSession = mockPlaceholderDrmSession;
|
||||||
ArgumentMatchers.any(), ArgumentMatchers.anyInt()))
|
|
||||||
.thenReturn(mockPlaceholderDrmSession);
|
|
||||||
|
|
||||||
writeFormat(ENCRYPTED_SAMPLE_FORMATS[0]);
|
writeFormat(ENCRYPTED_SAMPLE_FORMATS[0]);
|
||||||
byte[] sampleData = new byte[] {0, 1, 2};
|
byte[] sampleData = new byte[] {0, 1, 2};
|
||||||
@ -540,7 +535,7 @@ public final class SampleQueueTest {
|
|||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
||||||
writeTestDataWithEncryptedSections();
|
writeTestDataWithEncryptedSections();
|
||||||
|
|
||||||
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED);
|
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED_WITH_EXO_MEDIA_CRYPTO_TYPE);
|
||||||
assertReadNothing(/* formatRequired= */ false);
|
assertReadNothing(/* formatRequired= */ false);
|
||||||
sampleQueue.maybeThrowError();
|
sampleQueue.maybeThrowError();
|
||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_ERROR);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_ERROR);
|
||||||
@ -569,7 +564,7 @@ public final class SampleQueueTest {
|
|||||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
||||||
writeTestDataWithEncryptedSections();
|
writeTestDataWithEncryptedSections();
|
||||||
|
|
||||||
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED);
|
assertReadFormat(/* formatRequired= */ false, FORMAT_ENCRYPTED_WITH_EXO_MEDIA_CRYPTO_TYPE);
|
||||||
assertReadEncryptedSample(/* sampleIndex= */ 0);
|
assertReadEncryptedSample(/* sampleIndex= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,4 +1492,33 @@ public final class SampleQueueTest {
|
|||||||
private static Format copyWithLabel(Format format, String label) {
|
private static Format copyWithLabel(Format format, String label) {
|
||||||
return format.buildUpon().setLabel(label).build();
|
return format.buildUpon().setLabel(label).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class MockExoMediaCrypto implements ExoMediaCrypto {}
|
||||||
|
|
||||||
|
private static final class MockDrmSessionManager implements DrmSessionManager {
|
||||||
|
|
||||||
|
private final DrmSession mockDrmSession;
|
||||||
|
@Nullable private DrmSession mockPlaceholderDrmSession;
|
||||||
|
|
||||||
|
private MockDrmSessionManager(DrmSession mockDrmSession) {
|
||||||
|
this.mockDrmSession = mockDrmSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public DrmSession acquireSession(
|
||||||
|
Looper playbackLooper,
|
||||||
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
|
Format format) {
|
||||||
|
return format.drmInitData != null ? mockDrmSession : mockPlaceholderDrmSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Class<? extends ExoMediaCrypto> getExoMediaCryptoType(Format format) {
|
||||||
|
return mockPlaceholderDrmSession != null || format.drmInitData != null
|
||||||
|
? MockExoMediaCrypto.class
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|||||||
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
||||||
import com.google.android.exoplayer2.source.SampleStream;
|
import com.google.android.exoplayer2.source.SampleStream;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -274,10 +273,7 @@ public class FakeSampleStream implements SampleStream {
|
|||||||
@Nullable DrmSession previousSession = currentDrmSession;
|
@Nullable DrmSession previousSession = currentDrmSession;
|
||||||
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
|
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
|
||||||
currentDrmSession =
|
currentDrmSession =
|
||||||
newDrmInitData != null
|
drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat);
|
||||||
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat)
|
|
||||||
: drmSessionManager.acquirePlaceholderSession(
|
|
||||||
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
|
||||||
outputFormatHolder.drmSession = currentDrmSession;
|
outputFormatHolder.drmSession = currentDrmSession;
|
||||||
|
|
||||||
if (previousSession != null) {
|
if (previousSession != null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user