Add EventDispatcher to DrmSession(Manager) acquire & release calls

This is passed in but not currently used. I'll use it in follow-up
changes.

Pre-work for issue:#6765

PiperOrigin-RevId: 299314341
This commit is contained in:
ibaker 2020-03-06 10:55:01 +00:00 committed by Oliver Woodman
parent 1f4156ce6d
commit eeab811301
14 changed files with 127 additions and 55 deletions

View File

@ -33,6 +33,7 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventDispatcher;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.Arrays;
@ -258,7 +259,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
@Override
public void acquire() {
public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) {
Assertions.checkState(referenceCount >= 0);
if (++referenceCount == 1) {
Assertions.checkState(state == STATE_OPENING);
@ -272,7 +273,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
@Override
public void release() {
public void release(@Nullable MediaSourceEventDispatcher eventDispatcher) {
if (--referenceCount == 0) {
// Assigning null to various non-null variables for clean-up.
state = STATE_RELEASED;
@ -288,7 +289,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
if (sessionId != null) {
mediaDrm.closeSession(sessionId);
sessionId = null;
eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionReleased);
this.eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionReleased);
}
releaseCallback.onSessionReleased(this);
}

View File

@ -31,6 +31,7 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventDispatcher;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@ -386,8 +387,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
/**
* Sets the mode, which determines the role of sessions acquired from the instance. This must be
* called before {@link #acquireSession(Looper, DrmInitData)} or {@link
* #acquirePlaceholderSession} is called.
* called before {@link #acquireSession(Looper, MediaSourceEventDispatcher, DrmInitData)} or
* {@link #acquirePlaceholderSession} is called.
*
* <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when
* required.
@ -490,12 +491,15 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
sessions.add(placeholderDrmSession);
this.placeholderDrmSession = placeholderDrmSession;
}
placeholderDrmSession.acquire();
placeholderDrmSession.acquire(/* eventDispatcher= */ null);
return placeholderDrmSession;
}
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
public DrmSession<T> acquireSession(
Looper playbackLooper,
@Nullable MediaSourceEventDispatcher eventDispatcher,
DrmInitData drmInitData) {
assertExpectedPlaybackLooper(playbackLooper);
maybeCreateMediaDrmHandler(playbackLooper);
@ -504,7 +508,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
schemeDatas = getSchemeDatas(drmInitData, uuid, false);
if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
this.eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
return new ErrorStateDrmSession<>(new DrmSessionException(error));
}
}
@ -531,7 +535,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
}
sessions.add(session);
}
session.acquire();
session.acquire(eventDispatcher);
return session;
}

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm;
import android.media.MediaDrm;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@ -30,8 +31,11 @@ import java.util.Map;
public interface DrmSession<T extends ExoMediaCrypto> {
/**
* Invokes {@code newSession's} {@link #acquire()} and {@code previousSession's} {@link
* #release()} in that order. Null arguments are ignored. Does nothing if {@code previousSession}
* Acquires {@code newSession} then releases {@code previousSession}.
*
* <p>Invokes {@code newSession's} {@link #acquire(MediaSourceEventDispatcher)} and {@code
* previousSession's} {@link #release(MediaSourceEventDispatcher)} in that order (passing {@code
* eventDispatcher = null}). Null arguments are ignored. Does nothing if {@code previousSession}
* and {@code newSession} are the same session.
*/
static <T extends ExoMediaCrypto> void replaceSession(
@ -41,10 +45,10 @@ public interface DrmSession<T extends ExoMediaCrypto> {
return;
}
if (newSession != null) {
newSession.acquire();
newSession.acquire(/* eventDispatcher= */ null);
}
if (previousSession != null) {
previousSession.release();
previousSession.release(/* eventDispatcher= */ null);
}
}
@ -132,13 +136,20 @@ public interface DrmSession<T extends ExoMediaCrypto> {
/**
* Increments the reference count. When the caller no longer needs to use the instance, it must
* call {@link #release()} to decrement the reference count.
* call {@link #release(MediaSourceEventDispatcher)} to decrement the reference count.
*
* @param eventDispatcher The {@link MediaSourceEventDispatcher} used to route DRM-related events
* dispatched from this session, or null if no event handling is needed.
*/
void acquire();
void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher);
/**
* Decrements the reference count. If the reference count drops to 0 underlying resources are
* released, and the instance cannot be re-used.
*
* @param eventDispatcher The {@link MediaSourceEventDispatcher} to disconnect when the session is
* released (the same instance (possibly null) that was passed by the caller to {@link
* #acquire(MediaSourceEventDispatcher)}).
*/
void release();
void release(@Nullable MediaSourceEventDispatcher eventDispatcher);
}

View File

@ -19,6 +19,7 @@ import android.os.Looper;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
/**
* Manages a DRM session.
@ -42,7 +43,9 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
@Override
public DrmSession<ExoMediaCrypto> acquireSession(
Looper playbackLooper, DrmInitData drmInitData) {
Looper playbackLooper,
@Nullable MediaSourceEventDispatcher eventDispatcher,
DrmInitData drmInitData) {
return new ErrorStateDrmSession<>(
new DrmSession.DrmSessionException(
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
@ -83,7 +86,7 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
/**
* 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()} to decrement the reference count.
* DrmSession#release(MediaSourceEventDispatcher)} 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
@ -103,14 +106,19 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
/**
* Returns a {@link DrmSession} for the specified {@link DrmInitData}, with an incremented
* reference count. When the caller no longer needs to use the instance, it must call {@link
* DrmSession#release()} to decrement the reference count.
* DrmSession#release(MediaSourceEventDispatcher)} to decrement the reference count.
*
* @param playbackLooper The looper associated with the media playback thread.
* @param eventDispatcher The {@link MediaSourceEventDispatcher} used to distribute events, and
* passed on to {@link DrmSession#acquire(MediaSourceEventDispatcher)}.
* @param drmInitData DRM initialization data. All contained {@link SchemeData}s must contain
* non-null {@link SchemeData#data}.
* @return The DRM session.
*/
DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData);
DrmSession<T> acquireSession(
Looper playbackLooper,
@Nullable MediaSourceEventDispatcher eventDispatcher,
DrmInitData drmInitData);
/**
* Returns the {@link ExoMediaCrypto} type returned by sessions acquired using the given {@link

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.util.Map;
/** A {@link DrmSession} that's in a terminal error state. */
@ -63,12 +64,12 @@ public final class ErrorStateDrmSession<T extends ExoMediaCrypto> implements Drm
}
@Override
public void acquire() {
public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) {
// Do nothing.
}
@Override
public void release() {
public void release(@Nullable MediaSourceEventDispatcher eventDispatcher) {
// Do nothing.
}
}

View File

@ -26,8 +26,8 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource.Factory;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
@ -41,6 +41,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
private final ConditionVariable conditionVariable;
private final DefaultDrmSessionManager<T> drmSessionManager;
private final HandlerThread handlerThread;
private final MediaSourceEventDispatcher eventDispatcher;
/**
* Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance
@ -49,14 +50,18 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL.
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
*/
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
String defaultLicenseUrl, Factory httpDataSourceFactory)
String defaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, null);
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, eventDispatcher);
}
/**
@ -68,15 +73,24 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that
* include their own license URL.
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
*/
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
String defaultLicenseUrl, boolean forceDefaultLicenseUrl, Factory httpDataSourceFactory)
String defaultLicenseUrl,
boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
return newWidevineInstance(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory,
null);
return newWidevineInstance(
defaultLicenseUrl,
forceDefaultLicenseUrl,
httpDataSourceFactory,
/* optionalKeyRequestParameters= */ null,
eventDispatcher);
}
/**
@ -89,6 +103,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* include their own license URL.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link MediaDrm#getKeyRequest}. May be null.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
@ -97,14 +113,16 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
String defaultLicenseUrl,
boolean forceDefaultLicenseUrl,
Factory httpDataSourceFactory,
@Nullable Map<String, String> optionalKeyRequestParameters)
HttpDataSource.Factory httpDataSourceFactory,
@Nullable Map<String, String> optionalKeyRequestParameters,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
return new OfflineLicenseHelper<>(
C.WIDEVINE_UUID,
FrameworkMediaDrm.DEFAULT_PROVIDER,
new HttpMediaDrmCallback(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory),
optionalKeyRequestParameters);
optionalKeyRequestParameters,
eventDispatcher);
}
/**
@ -115,6 +133,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param callback Performs key and provisioning requests.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link MediaDrm#getKeyRequest}. May be null.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @see DefaultDrmSessionManager.Builder
*/
@SuppressWarnings("unchecked")
@ -122,7 +142,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
UUID uuid,
ExoMediaDrm.Provider<T> mediaDrmProvider,
MediaDrmCallback callback,
@Nullable Map<String, String> optionalKeyRequestParameters) {
@Nullable Map<String, String> optionalKeyRequestParameters,
MediaSourceEventDispatcher eventDispatcher) {
handlerThread = new HandlerThread("OfflineLicenseHelper");
handlerThread.start();
conditionVariable = new ConditionVariable();
@ -158,6 +179,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
.setKeyRequestParameters(optionalKeyRequestParameters)
.build(callback);
drmSessionManager.addListener(new Handler(handlerThread.getLooper()), eventListener);
this.eventDispatcher = eventDispatcher;
}
/**
@ -216,7 +238,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSession.release();
drmSession.release(eventDispatcher);
drmSessionManager.release();
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
@ -242,7 +264,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSession.release();
drmSession.release(eventDispatcher);
drmSessionManager.release();
if (error != null) {
throw error;
@ -254,8 +276,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) {
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
conditionVariable.close();
DrmSession<T> drmSession = drmSessionManager.acquireSession(handlerThread.getLooper(),
drmInitData);
DrmSession<T> drmSession =
drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, drmInitData);
// Block current thread until key loading is finished
conditionVariable.block();
return drmSession;

View File

@ -675,7 +675,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return sampleQueues[i];
}
}
SampleQueue trackOutput = new SampleQueue(allocator, drmSessionManager);
SampleQueue trackOutput = new SampleQueue(allocator, drmSessionManager, eventDispatcher);
trackOutput.setUpstreamFormatChangeListener(this);
@NullableType
TrackId[] sampleQueueTrackIds = Arrays.copyOf(this.sampleQueueTrackIds, trackCount + 1);

View File

@ -30,6 +30,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataReader;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
@ -55,6 +56,7 @@ public class SampleQueue implements TrackOutput {
private final SampleDataQueue sampleDataQueue;
private final SampleExtrasHolder extrasHolder;
private final DrmSessionManager<?> drmSessionManager;
private final MediaSourceEventDispatcher eventDispatcher;
@Nullable private UpstreamFormatChangedListener upstreamFormatChangeListener;
@Nullable private Format downstreamFormat;
@ -94,10 +96,16 @@ public class SampleQueue implements TrackOutput {
* @param allocator An {@link Allocator} from which allocations for sample data can be obtained.
* @param drmSessionManager The {@link DrmSessionManager} to obtain {@link DrmSession DrmSessions}
* from. The created instance does not take ownership of this {@link DrmSessionManager}.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} to notify of events related to this
* SampleQueue.
*/
public SampleQueue(Allocator allocator, DrmSessionManager<?> drmSessionManager) {
public SampleQueue(
Allocator allocator,
DrmSessionManager<?> drmSessionManager,
MediaSourceEventDispatcher eventDispatcher) {
sampleDataQueue = new SampleDataQueue(allocator);
this.drmSessionManager = drmSessionManager;
this.eventDispatcher = eventDispatcher;
extrasHolder = new SampleExtrasHolder();
capacity = SAMPLE_CAPACITY_INCREMENT;
sourceIds = new int[capacity];
@ -647,7 +655,7 @@ public class SampleQueue implements TrackOutput {
private void releaseDrmSessionReferences() {
if (currentDrmSession != null) {
currentDrmSession.release();
currentDrmSession.release(eventDispatcher);
currentDrmSession = null;
// Clear downstream format to avoid violating the assumption that downstreamFormat.drmInitData
// != null implies currentSession != null
@ -791,13 +799,13 @@ public class SampleQueue implements TrackOutput {
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
currentDrmSession =
newDrmInitData != null
? drmSessionManager.acquireSession(playbackLooper, newDrmInitData)
? drmSessionManager.acquireSession(playbackLooper, eventDispatcher, newDrmInitData)
: drmSessionManager.acquirePlaceholderSession(
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
outputFormatHolder.drmSession = currentDrmSession;
if (previousSession != null) {
previousSession.release();
previousSession.release(eventDispatcher);
}
}

View File

@ -131,13 +131,14 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
int[] trackTypes = new int[1 + embeddedTrackCount];
SampleQueue[] sampleQueues = new SampleQueue[1 + embeddedTrackCount];
primarySampleQueue = new SampleQueue(allocator, drmSessionManager);
primarySampleQueue = new SampleQueue(allocator, drmSessionManager, eventDispatcher);
trackTypes[0] = primaryTrackType;
sampleQueues[0] = primarySampleQueue;
for (int i = 0; i < embeddedTrackCount; i++) {
SampleQueue sampleQueue =
new SampleQueue(allocator, DrmSessionManager.getDummyDrmSessionManager());
new SampleQueue(
allocator, DrmSessionManager.getDummyDrmSessionManager(), eventDispatcher);
embeddedSampleQueues[i] = sampleQueue;
sampleQueues[i + 1] = sampleQueue;
trackTypes[i + 1] = this.embeddedTrackTypes[i];

View File

@ -25,6 +25,7 @@ import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.util.HashMap;
import org.junit.After;
import org.junit.Before;
@ -55,7 +56,8 @@ public class OfflineLicenseHelperTest {
C.WIDEVINE_UUID,
new ExoMediaDrm.AppManagedProvider<>(mediaDrm),
mediaDrmCallback,
null);
/* optionalKeyRequestParameters= */ null,
new MediaSourceEventDispatcher());
}
@After

View File

@ -40,6 +40,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
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.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException;
import java.util.Arrays;
@ -125,6 +126,7 @@ public final class SampleQueueTest {
private Allocator allocator;
private DrmSessionManager<ExoMediaCrypto> mockDrmSessionManager;
private DrmSession<ExoMediaCrypto> mockDrmSession;
private MediaSourceEventDispatcher eventDispatcher;
private SampleQueue sampleQueue;
private FormatHolder formatHolder;
private DecoderInputBuffer inputBuffer;
@ -136,9 +138,11 @@ public final class SampleQueueTest {
mockDrmSessionManager =
(DrmSessionManager<ExoMediaCrypto>) Mockito.mock(DrmSessionManager.class);
mockDrmSession = (DrmSession<ExoMediaCrypto>) Mockito.mock(DrmSession.class);
when(mockDrmSessionManager.acquireSession(ArgumentMatchers.any(), ArgumentMatchers.any()))
when(mockDrmSessionManager.acquireSession(
ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any()))
.thenReturn(mockDrmSession);
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager);
eventDispatcher = new MediaSourceEventDispatcher();
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
formatHolder = new FormatHolder();
inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
}
@ -355,7 +359,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, mockDrmSessionManager);
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
writeTestDataWithEncryptedSections();
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue();
}
@ -535,7 +539,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, mockDrmSessionManager);
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
writeTestDataWithEncryptedSections();
@ -925,7 +929,7 @@ public final class SampleQueueTest {
public void adjustUpstreamFormat() {
String label = "label";
sampleQueue =
new SampleQueue(allocator, mockDrmSessionManager) {
new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
@Override
public Format getAdjustedUpstreamFormat(Format format) {
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label));
@ -941,7 +945,7 @@ public final class SampleQueueTest {
public void invalidateUpstreamFormatAdjustment() {
AtomicReference<String> label = new AtomicReference<>("label1");
sampleQueue =
new SampleQueue(allocator, mockDrmSessionManager) {
new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
@Override
public Format getAdjustedUpstreamFormat(Format format) {
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label.get()));

View File

@ -35,6 +35,7 @@ import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataReader;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
@ -284,7 +285,11 @@ public final class PlayerEmsgHandler implements Handler.Callback {
private final MetadataInputBuffer buffer;
/* package */ PlayerTrackEmsgHandler(Allocator allocator) {
this.sampleQueue = new SampleQueue(allocator, DrmSessionManager.getDummyDrmSessionManager());
this.sampleQueue =
new SampleQueue(
allocator,
DrmSessionManager.getDummyDrmSessionManager(),
new MediaSourceEventDispatcher());
formatHolder = new FormatHolder();
buffer = new MetadataInputBuffer();
}

View File

@ -53,6 +53,7 @@ import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
@ -907,7 +908,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
boolean isAudioVideo = type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO;
FormatAdjustingSampleQueue trackOutput =
new FormatAdjustingSampleQueue(allocator, drmSessionManager, overridingDrmInitData);
new FormatAdjustingSampleQueue(
allocator, drmSessionManager, eventDispatcher, overridingDrmInitData);
if (isAudioVideo) {
trackOutput.setDrmInitData(drmInitData);
}
@ -1348,8 +1350,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public FormatAdjustingSampleQueue(
Allocator allocator,
DrmSessionManager<?> drmSessionManager,
MediaSourceEventDispatcher eventDispatcher,
Map<String, DrmInitData> overridingDrmInitData) {
super(allocator, drmSessionManager);
super(allocator, drmSessionManager, eventDispatcher);
this.overridingDrmInitData = overridingDrmInitData;
}

View File

@ -35,6 +35,7 @@ import com.google.android.exoplayer2.testutil.ActionSchedule;
import com.google.android.exoplayer2.testutil.HostActivity;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
@ -75,8 +76,9 @@ public final class DashWidevineOfflineTest {
String widevineLicenseUrl = DashTestData.getWidevineLicenseUrl(true, useL1Widevine);
httpDataSourceFactory = new DefaultHttpDataSourceFactory(USER_AGENT);
if (Util.SDK_INT >= 18) {
offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(widevineLicenseUrl,
httpDataSourceFactory);
offlineLicenseHelper =
OfflineLicenseHelper.newWidevineInstance(
widevineLicenseUrl, httpDataSourceFactory, new MediaSourceEventDispatcher());
}
}