Skip to content

Commit

Permalink
Introduce ExoMediaDrm.Provider into DefaultDrmSessionManager
Browse files Browse the repository at this point in the history
Issue:#4721
PiperOrigin-RevId: 271127127
  • Loading branch information
AquilesCanta authored and ojw28 committed Oct 2, 2019
1 parent e4cabca commit c2bab7a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private MissingSchemeDataException(UUID uuid) {
private static final String TAG = "DefaultDrmSessionMgr";

private final UUID uuid;
private final ExoMediaDrm<T> mediaDrm;
private final ExoMediaDrm.Provider<T> exoMediaDrmProvider;
private final MediaDrmCallback callback;
@Nullable private final HashMap<String, String> optionalKeyRequestParameters;
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
Expand All @@ -98,6 +98,8 @@ private MissingSchemeDataException(UUID uuid) {
private final List<DefaultDrmSession<T>> sessions;
private final List<DefaultDrmSession<T>> provisioningSessions;

private int prepareCallsCount;
@Nullable private ExoMediaDrm<T> exoMediaDrm;
@Nullable private DefaultDrmSession<T> placeholderDrmSession;
@Nullable private Looper playbackLooper;
private int mode;
Expand All @@ -107,19 +109,19 @@ private MissingSchemeDataException(UUID uuid) {

/**
* @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 optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
*/
public DefaultDrmSessionManager(
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters) {
this(
uuid,
mediaDrm,
exoMediaDrm,
callback,
optionalKeyRequestParameters,
/* multiSession= */ false,
Expand All @@ -128,7 +130,7 @@ public DefaultDrmSessionManager(

/**
* @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 optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
Expand All @@ -137,13 +139,13 @@ public DefaultDrmSessionManager(
*/
public DefaultDrmSessionManager(
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession) {
this(
uuid,
mediaDrm,
exoMediaDrm,
callback,
optionalKeyRequestParameters,
multiSession,
Expand All @@ -152,7 +154,7 @@ public DefaultDrmSessionManager(

/**
* @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 optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
Expand All @@ -163,14 +165,14 @@ public DefaultDrmSessionManager(
*/
public DefaultDrmSessionManager(
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession,
int initialDrmRequestRetryCount) {
this(
uuid,
mediaDrm,
new ExoMediaDrm.AppManagedProvider<>(exoMediaDrm),
callback,
optionalKeyRequestParameters,
multiSession,
Expand All @@ -180,38 +182,26 @@ public DefaultDrmSessionManager(

private DefaultDrmSessionManager(
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ExoMediaDrm.Provider<T> exoMediaDrmProvider,
MediaDrmCallback callback,
@Nullable HashMap<String, String> optionalKeyRequestParameters,
boolean multiSession,
boolean allowPlaceholderSessions,
LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
Assertions.checkNotNull(uuid);
Assertions.checkNotNull(mediaDrm);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
this.uuid = uuid;
this.mediaDrm = mediaDrm;
this.exoMediaDrmProvider = exoMediaDrmProvider;
this.callback = callback;
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.allowPlaceholderSessions = allowPlaceholderSessions;
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
mode = MODE_PLAYBACK;
sessions = 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());
}

/**
Expand Down Expand Up @@ -268,6 +258,30 @@ public void setMode(@Mode int mode, @Nullable byte[] offlineLicenseKeySetId) {

// DrmSessionManager implementation.

@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) {
if (offlineLicenseKeySetId != null) {
Expand Down Expand Up @@ -304,7 +318,13 @@ public boolean canAcquireSession(DrmInitData drmInitData) {
@Nullable
public DrmSession<T> acquirePlaceholderSession(Looper 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;
}
maybeCreateMediaDrmHandler(playbackLooper);
Expand Down Expand Up @@ -359,7 +379,9 @@ public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitDa
@Override
@Nullable
public Class<T> getExoMediaCryptoType(DrmInitData drmInitData) {
return canAcquireSession(drmInitData) ? mediaDrm.getExoMediaCryptoType() : null;
return canAcquireSession(drmInitData)
? Assertions.checkNotNull(exoMediaDrm).getExoMediaCryptoType()
: null;
}

// ProvisioningManager implementation.
Expand Down Expand Up @@ -408,9 +430,10 @@ private void maybeCreateMediaDrmHandler(Looper playbackLooper) {

private DefaultDrmSession<T> createNewDefaultSession(
@Nullable List<SchemeData> schemeDatas, boolean isPlaceholderSession) {
Assertions.checkNotNull(exoMediaDrm);
return new DefaultDrmSession<>(
uuid,
mediaDrm,
exoMediaDrm,
/* provisioningManager= */ this,
/* releaseCallback= */ this::onSessionReleased,
schemeDatas,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,15 @@ public synchronized void releaseLicense(byte[] offlineLicenseKeySetId)
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
drmSessionManager.prepare();
DrmSession<T> drmSession =
openBlockingKeyRequest(
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSession.releaseReference();
drmSessionManager.release();
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
Expand All @@ -227,11 +229,13 @@ public void release() {
private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
throws DrmSessionException {
drmSessionManager.prepare();
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSession.releaseReference();
drmSessionManager.release();
if (error != null) {
throw error;
}
Expand Down

0 comments on commit c2bab7a

Please sign in to comment.