Commit c2bab7a7 by aquilescanta Committed by Oliver Woodman

Introduce ExoMediaDrm.Provider into DefaultDrmSessionManager

Issue:#4721
PiperOrigin-RevId: 271127127
parent e4cabcac
...@@ -87,7 +87,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -87,7 +87,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
private static final String TAG = "DefaultDrmSessionMgr"; private static final String TAG = "DefaultDrmSessionMgr";
private final UUID uuid; private final UUID uuid;
private final ExoMediaDrm<T> mediaDrm; private final ExoMediaDrm.Provider<T> exoMediaDrmProvider;
private final MediaDrmCallback callback; private final MediaDrmCallback callback;
@Nullable private final HashMap<String, String> optionalKeyRequestParameters; @Nullable private final HashMap<String, String> optionalKeyRequestParameters;
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher; private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
...@@ -98,6 +98,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -98,6 +98,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
private final List<DefaultDrmSession<T>> sessions; private final List<DefaultDrmSession<T>> sessions;
private final List<DefaultDrmSession<T>> provisioningSessions; private final List<DefaultDrmSession<T>> provisioningSessions;
private int prepareCallsCount;
@Nullable private ExoMediaDrm<T> exoMediaDrm;
@Nullable private DefaultDrmSession<T> placeholderDrmSession; @Nullable private DefaultDrmSession<T> placeholderDrmSession;
@Nullable private Looper playbackLooper; @Nullable private Looper playbackLooper;
private int mode; private int mode;
...@@ -107,19 +109,19 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -107,19 +109,19 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
/** /**
* @param uuid The UUID of the drm scheme. * @param uuid The UUID of the drm scheme.
* @param mediaDrm An underlying {@link ExoMediaDrm} for use by the manager. * @param exoMediaDrm An underlying {@link ExoMediaDrm} for use by the manager.
* @param callback Performs key and provisioning requests. * @param callback Performs key and provisioning requests.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null. * to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
*/ */
public DefaultDrmSessionManager( public DefaultDrmSessionManager(
UUID uuid, UUID uuid,
ExoMediaDrm<T> mediaDrm, ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback, MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters) { @Nullable HashMap<String, String> optionalKeyRequestParameters) {
this( this(
uuid, uuid,
mediaDrm, exoMediaDrm,
callback, callback,
optionalKeyRequestParameters, optionalKeyRequestParameters,
/* multiSession= */ false, /* multiSession= */ false,
...@@ -128,7 +130,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -128,7 +130,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
/** /**
* @param uuid The UUID of the drm scheme. * @param uuid The UUID of the drm scheme.
* @param mediaDrm An underlying {@link ExoMediaDrm} for use by the manager. * @param exoMediaDrm An underlying {@link ExoMediaDrm} for use by the manager.
* @param callback Performs key and provisioning requests. * @param callback Performs key and provisioning requests.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null. * to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
...@@ -137,13 +139,13 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -137,13 +139,13 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
*/ */
public DefaultDrmSessionManager( public DefaultDrmSessionManager(
UUID uuid, UUID uuid,
ExoMediaDrm<T> mediaDrm, ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback, MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters, @Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession) { boolean multiSession) {
this( this(
uuid, uuid,
mediaDrm, exoMediaDrm,
callback, callback,
optionalKeyRequestParameters, optionalKeyRequestParameters,
multiSession, multiSession,
...@@ -152,7 +154,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -152,7 +154,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
/** /**
* @param uuid The UUID of the drm scheme. * @param uuid The UUID of the drm scheme.
* @param mediaDrm An underlying {@link ExoMediaDrm} for use by the manager. * @param exoMediaDrm An underlying {@link ExoMediaDrm} for use by the manager.
* @param callback Performs key and provisioning requests. * @param callback Performs key and provisioning requests.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null. * to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
...@@ -163,14 +165,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -163,14 +165,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
*/ */
public DefaultDrmSessionManager( public DefaultDrmSessionManager(
UUID uuid, UUID uuid,
ExoMediaDrm<T> mediaDrm, ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback, MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters, @Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession, boolean multiSession,
int initialDrmRequestRetryCount) { int initialDrmRequestRetryCount) {
this( this(
uuid, uuid,
mediaDrm, new ExoMediaDrm.AppManagedProvider<>(exoMediaDrm),
callback, callback,
optionalKeyRequestParameters, optionalKeyRequestParameters,
multiSession, multiSession,
...@@ -180,38 +182,26 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -180,38 +182,26 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
private DefaultDrmSessionManager( private DefaultDrmSessionManager(
UUID uuid, UUID uuid,
ExoMediaDrm<T> mediaDrm, ExoMediaDrm.Provider<T> exoMediaDrmProvider,
MediaDrmCallback callback, MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters, @Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession, boolean multiSession,
boolean allowPlaceholderSessions, boolean allowPlaceholderSessions,
LoadErrorHandlingPolicy loadErrorHandlingPolicy) { LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
Assertions.checkNotNull(uuid); Assertions.checkNotNull(uuid);
Assertions.checkNotNull(mediaDrm);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead"); Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
this.uuid = uuid; this.uuid = uuid;
this.mediaDrm = mediaDrm; this.exoMediaDrmProvider = exoMediaDrmProvider;
this.callback = callback; this.callback = callback;
this.optionalKeyRequestParameters = optionalKeyRequestParameters; this.optionalKeyRequestParameters = optionalKeyRequestParameters;
this.eventDispatcher = new EventDispatcher<>(); this.eventDispatcher = new EventDispatcher<>();
this.multiSession = multiSession; this.multiSession = multiSession;
boolean canAcquirePlaceholderSessions =
!FrameworkMediaCrypto.class.equals(mediaDrm.getExoMediaCryptoType())
|| !FrameworkMediaCrypto.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC;
// TODO: Allow customization once this class has a Builder. // TODO: Allow customization once this class has a Builder.
this.allowPlaceholderSessions = canAcquirePlaceholderSessions && allowPlaceholderSessions; this.allowPlaceholderSessions = allowPlaceholderSessions;
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy; this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
mode = MODE_PLAYBACK; mode = MODE_PLAYBACK;
sessions = new ArrayList<>(); sessions = new ArrayList<>();
provisioningSessions = new ArrayList<>(); provisioningSessions = new ArrayList<>();
if (multiSession && C.WIDEVINE_UUID.equals(uuid) && Util.SDK_INT >= 19) {
// TODO: Enabling session sharing probably doesn't do anything useful here. It would only be
// useful if DefaultDrmSession instances were aware of one another's state, which is not
// implemented. Or if custom renderers are being used that allow playback to proceed before
// keys, which seems unlikely to be true in practice.
mediaDrm.setPropertyString("sessionSharing", "enable");
}
mediaDrm.setOnEventListener(new MediaDrmEventListener());
} }
/** /**
...@@ -269,6 +259,30 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -269,6 +259,30 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
// DrmSessionManager implementation. // DrmSessionManager implementation.
@Override @Override
public final void prepare() {
if (prepareCallsCount++ == 0) {
Assertions.checkState(exoMediaDrm == null);
exoMediaDrm = exoMediaDrmProvider.acquireExoMediaDrm(uuid);
if (multiSession && C.WIDEVINE_UUID.equals(uuid) && Util.SDK_INT >= 19) {
// TODO: Enabling session sharing probably doesn't do anything useful here. It would only be
// useful if DefaultDrmSession instances were aware of one another's state, which is not
// implemented. Or if custom renderers are being used that allow playback to proceed before
// keys, which seems unlikely to be true in practice.
exoMediaDrm.setPropertyString("sessionSharing", "enable");
}
exoMediaDrm.setOnEventListener(new MediaDrmEventListener());
}
}
@Override
public final void release() {
if (--prepareCallsCount == 0) {
Assertions.checkNotNull(exoMediaDrm).release();
exoMediaDrm = null;
}
}
@Override
public boolean canAcquireSession(DrmInitData drmInitData) { public 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.
...@@ -304,7 +318,13 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -304,7 +318,13 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
@Nullable @Nullable
public DrmSession<T> acquirePlaceholderSession(Looper playbackLooper) { public DrmSession<T> acquirePlaceholderSession(Looper playbackLooper) {
assertExpectedPlaybackLooper(playbackLooper); assertExpectedPlaybackLooper(playbackLooper);
if (!allowPlaceholderSessions || mediaDrm.getExoMediaCryptoType() == null) { Assertions.checkNotNull(exoMediaDrm);
boolean avoidPlaceholderDrmSessions =
FrameworkMediaCrypto.class.equals(exoMediaDrm.getExoMediaCryptoType())
&& FrameworkMediaCrypto.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC;
if (avoidPlaceholderDrmSessions
|| !allowPlaceholderSessions
|| exoMediaDrm.getExoMediaCryptoType() == null) {
return null; return null;
} }
maybeCreateMediaDrmHandler(playbackLooper); maybeCreateMediaDrmHandler(playbackLooper);
...@@ -359,7 +379,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -359,7 +379,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
@Override @Override
@Nullable @Nullable
public Class<T> getExoMediaCryptoType(DrmInitData drmInitData) { public Class<T> getExoMediaCryptoType(DrmInitData drmInitData) {
return canAcquireSession(drmInitData) ? mediaDrm.getExoMediaCryptoType() : null; return canAcquireSession(drmInitData)
? Assertions.checkNotNull(exoMediaDrm).getExoMediaCryptoType()
: null;
} }
// ProvisioningManager implementation. // ProvisioningManager implementation.
...@@ -408,9 +430,10 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> ...@@ -408,9 +430,10 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
private DefaultDrmSession<T> createNewDefaultSession( private DefaultDrmSession<T> createNewDefaultSession(
@Nullable List<SchemeData> schemeDatas, boolean isPlaceholderSession) { @Nullable List<SchemeData> schemeDatas, boolean isPlaceholderSession) {
Assertions.checkNotNull(exoMediaDrm);
return new DefaultDrmSession<>( return new DefaultDrmSession<>(
uuid, uuid,
mediaDrm, exoMediaDrm,
/* provisioningManager= */ this, /* provisioningManager= */ this,
/* releaseCallback= */ this::onSessionReleased, /* releaseCallback= */ this::onSessionReleased,
schemeDatas, schemeDatas,
......
...@@ -201,6 +201,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> { ...@@ -201,6 +201,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
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.prepare();
DrmSession<T> drmSession = DrmSession<T> drmSession =
openBlockingKeyRequest( openBlockingKeyRequest(
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA); DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
...@@ -208,6 +209,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> { ...@@ -208,6 +209,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
Pair<Long, Long> licenseDurationRemainingSec = Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession); WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSession.releaseReference(); drmSession.releaseReference();
drmSessionManager.release();
if (error != null) { if (error != null) {
if (error.getCause() instanceof KeysExpiredException) { if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L); return Pair.create(0L, 0L);
...@@ -227,11 +229,13 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> { ...@@ -227,11 +229,13 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
private byte[] blockingKeyRequest( private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
throws DrmSessionException { throws DrmSessionException {
drmSessionManager.prepare();
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData); drmInitData);
DrmSessionException error = drmSession.getError(); DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId(); byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSession.releaseReference(); drmSession.releaseReference();
drmSessionManager.release();
if (error != null) { if (error != null) {
throw error; throw error;
} }
......
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