mirror of
https://github.com/androidx/media.git
synced 2025-05-06 23:20:42 +08:00
Implement acquirePlaceholderSession in DefaultDrmSessionManager
Issue:#4867 PiperOrigin-RevId: 268497377
This commit is contained in:
parent
f7e9e185f7
commit
143d7d6cca
@ -93,11 +93,13 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
@Nullable private final HashMap<String, String> optionalKeyRequestParameters;
|
||||
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
|
||||
private final boolean multiSession;
|
||||
private final boolean allowPlaceholderSessions;
|
||||
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
|
||||
|
||||
private final List<DefaultDrmSession<T>> sessions;
|
||||
private final List<DefaultDrmSession<T>> provisioningSessions;
|
||||
|
||||
@Nullable private DefaultDrmSession<T> placeholderDrmSession;
|
||||
@Nullable private Looper playbackLooper;
|
||||
private int mode;
|
||||
@Nullable private byte[] offlineLicenseKeySetId;
|
||||
@ -232,6 +234,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
callback,
|
||||
optionalKeyRequestParameters,
|
||||
multiSession,
|
||||
/* allowPlaceholderSessions= */ false,
|
||||
new DefaultLoadErrorHandlingPolicy(initialDrmRequestRetryCount));
|
||||
}
|
||||
|
||||
@ -241,6 +244,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
MediaDrmCallback callback,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
boolean multiSession,
|
||||
boolean allowPlaceholderSessions,
|
||||
LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
||||
Assertions.checkNotNull(uuid);
|
||||
Assertions.checkNotNull(mediaDrm);
|
||||
@ -251,6 +255,11 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
|
||||
this.eventDispatcher = new EventDispatcher<>();
|
||||
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.
|
||||
this.allowPlaceholderSessions = canAcquirePlaceholderSessions && allowPlaceholderSessions;
|
||||
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
|
||||
mode = MODE_PLAYBACK;
|
||||
sessions = new ArrayList<>();
|
||||
@ -398,15 +407,26 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DrmSession<T> acquirePlaceholderSession(Looper playbackLooper) {
|
||||
if (!allowPlaceholderSessions) {
|
||||
return null;
|
||||
}
|
||||
maybeCreateMediaDrmHandler(playbackLooper);
|
||||
if (placeholderDrmSession == null) {
|
||||
DefaultDrmSession<T> placeholderDrmSession =
|
||||
createNewDefaultSession(/* schemeDatas= */ null, /* isPlaceholderSession= */ true);
|
||||
sessions.add(placeholderDrmSession);
|
||||
this.placeholderDrmSession = placeholderDrmSession;
|
||||
}
|
||||
placeholderDrmSession.acquireReference();
|
||||
return placeholderDrmSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
|
||||
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
|
||||
if (sessions.isEmpty()) {
|
||||
this.playbackLooper = playbackLooper;
|
||||
if (mediaDrmHandler == null) {
|
||||
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
|
||||
}
|
||||
}
|
||||
maybeCreateMediaDrmHandler(playbackLooper);
|
||||
|
||||
List<SchemeData> schemeDatas = null;
|
||||
if (offlineLicenseKeySetId == null) {
|
||||
@ -434,25 +454,39 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
|
||||
if (session == null) {
|
||||
// Create a new session.
|
||||
session =
|
||||
new DefaultDrmSession<>(
|
||||
session = createNewDefaultSession(schemeDatas, /* isPlaceholderSession= */ false);
|
||||
sessions.add(session);
|
||||
}
|
||||
session.acquireReference();
|
||||
return session;
|
||||
}
|
||||
|
||||
private DefaultDrmSession<T> createNewDefaultSession(
|
||||
@Nullable List<SchemeData> schemeDatas, boolean isPlaceholderSession) {
|
||||
return new DefaultDrmSession<>(
|
||||
uuid,
|
||||
mediaDrm,
|
||||
/* provisioningManager= */ this,
|
||||
/* releaseCallback= */ this::onSessionReleased,
|
||||
schemeDatas,
|
||||
mode,
|
||||
/* isPlaceholderSession= */ false,
|
||||
isPlaceholderSession,
|
||||
offlineLicenseKeySetId,
|
||||
optionalKeyRequestParameters,
|
||||
callback,
|
||||
playbackLooper,
|
||||
Assertions.checkNotNull(playbackLooper),
|
||||
eventDispatcher,
|
||||
loadErrorHandlingPolicy);
|
||||
sessions.add(session);
|
||||
}
|
||||
session.acquireReference();
|
||||
return session;
|
||||
|
||||
private void maybeCreateMediaDrmHandler(Looper playbackLooper) {
|
||||
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
|
||||
if (sessions.isEmpty()) {
|
||||
this.playbackLooper = playbackLooper;
|
||||
if (mediaDrmHandler == null) {
|
||||
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -496,6 +530,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
||||
|
||||
private void onSessionReleased(DefaultDrmSession<T> drmSession) {
|
||||
sessions.remove(drmSession);
|
||||
if (placeholderDrmSession == drmSession) {
|
||||
placeholderDrmSession = null;
|
||||
}
|
||||
if (provisioningSessions.size() > 1 && provisioningSessions.get(0) == drmSession) {
|
||||
// Other sessions were waiting for the released session to complete a provision operation.
|
||||
// We need to have one of those sessions perform the provision operation instead.
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.drm;
|
||||
|
||||
import android.media.MediaCrypto;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -24,6 +25,15 @@ import java.util.UUID;
|
||||
*/
|
||||
public final class FrameworkMediaCrypto implements ExoMediaCrypto {
|
||||
|
||||
/**
|
||||
* Whether the device needs keys to have been loaded into the {@link DrmSession} before codec
|
||||
* configuration.
|
||||
*/
|
||||
public static final boolean WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC =
|
||||
"Amazon".equals(Util.MANUFACTURER)
|
||||
&& ("AFTM".equals(Util.MODEL) // Fire TV Stick Gen 1
|
||||
|| "AFTB".equals(Util.MODEL)); // Fire TV Gen 1
|
||||
|
||||
/** The DRM scheme UUID. */
|
||||
public final UUID uuid;
|
||||
/** The DRM session id. */
|
||||
|
@ -521,7 +521,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
&& mediaCrypto.requiresSecureDecoderComponent(mimeType);
|
||||
}
|
||||
}
|
||||
if (deviceNeedsDrmKeysToConfigureCodecWorkaround()) {
|
||||
if (FrameworkMediaCrypto.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC) {
|
||||
@DrmSession.State int drmSessionState = codecDrmSession.getState();
|
||||
if (drmSessionState == DrmSession.STATE_ERROR) {
|
||||
throw ExoPlaybackException.createForRenderer(codecDrmSession.getError(), getIndex());
|
||||
@ -1754,16 +1754,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
return error instanceof MediaCodec.CodecException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the device needs keys to have been loaded into the {@link DrmSession} before
|
||||
* codec configuration.
|
||||
*/
|
||||
private boolean deviceNeedsDrmKeysToConfigureCodecWorkaround() {
|
||||
return "Amazon".equals(Util.MANUFACTURER)
|
||||
&& ("AFTM".equals(Util.MODEL) // Fire TV Stick Gen 1
|
||||
|| "AFTB".equals(Util.MODEL)); // Fire TV Gen 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the decoder is known to fail when flushed.
|
||||
* <p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user