mirror of
https://github.com/androidx/media.git
synced 2025-05-16 20:19:57 +08:00
Fix drm nullability warnings.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=213650027
This commit is contained in:
parent
6323c1904f
commit
b07eef6d44
@ -28,14 +28,19 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
|
||||
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.Util;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* A {@link DrmSession} that supports playbacks using {@link ExoMediaDrm}.
|
||||
@ -84,7 +89,7 @@ import java.util.UUID;
|
||||
private final ExoMediaDrm<T> mediaDrm;
|
||||
private final ProvisioningManager<T> provisioningManager;
|
||||
private final @DefaultDrmSessionManager.Mode int mode;
|
||||
private final HashMap<String, String> optionalKeyRequestParameters;
|
||||
private final @Nullable HashMap<String, String> optionalKeyRequestParameters;
|
||||
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
|
||||
private final int initialDrmRequestRetryCount;
|
||||
|
||||
@ -96,13 +101,13 @@ import java.util.UUID;
|
||||
private int openCount;
|
||||
private HandlerThread requestHandlerThread;
|
||||
private PostRequestHandler postRequestHandler;
|
||||
private T mediaCrypto;
|
||||
private DrmSessionException lastException;
|
||||
private byte[] sessionId;
|
||||
private @Nullable byte[] offlineLicenseKeySetId;
|
||||
private @Nullable T mediaCrypto;
|
||||
private @Nullable DrmSessionException lastException;
|
||||
private byte @MonotonicNonNull [] sessionId;
|
||||
private byte @MonotonicNonNull [] offlineLicenseKeySetId;
|
||||
|
||||
private KeyRequest currentKeyRequest;
|
||||
private ProvisionRequest currentProvisionRequest;
|
||||
private @Nullable KeyRequest currentKeyRequest;
|
||||
private @Nullable ProvisionRequest currentProvisionRequest;
|
||||
|
||||
/**
|
||||
* Instantiates a new DRM session.
|
||||
@ -129,18 +134,25 @@ import java.util.UUID;
|
||||
@Nullable List<SchemeData> schemeDatas,
|
||||
@DefaultDrmSessionManager.Mode int mode,
|
||||
@Nullable byte[] offlineLicenseKeySetId,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
MediaDrmCallback callback,
|
||||
Looper playbackLooper,
|
||||
EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher,
|
||||
int initialDrmRequestRetryCount) {
|
||||
if (mode == DefaultDrmSessionManager.MODE_QUERY
|
||||
|| mode == DefaultDrmSessionManager.MODE_RELEASE) {
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
}
|
||||
this.uuid = uuid;
|
||||
this.provisioningManager = provisioningManager;
|
||||
this.mediaDrm = mediaDrm;
|
||||
this.mode = mode;
|
||||
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
||||
this.schemeDatas =
|
||||
offlineLicenseKeySetId == null ? Collections.unmodifiableList(schemeDatas) : null;
|
||||
if (offlineLicenseKeySetId != null) {
|
||||
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
||||
this.schemeDatas = null;
|
||||
} else {
|
||||
this.schemeDatas = Collections.unmodifiableList(Assertions.checkNotNull(schemeDatas));
|
||||
}
|
||||
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
|
||||
this.callback = callback;
|
||||
this.initialDrmRequestRetryCount = initialDrmRequestRetryCount;
|
||||
@ -166,9 +178,9 @@ import java.util.UUID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the session is closed and cleaned up, false otherwise.
|
||||
*/
|
||||
/** @return True if the session is closed and cleaned up, false otherwise. */
|
||||
// Assigning null to various non-null variables for clean-up. Class won't be used after release.
|
||||
@SuppressWarnings("assignment.type.incompatible")
|
||||
public boolean release() {
|
||||
if (--openCount == 0) {
|
||||
state = STATE_RELEASED;
|
||||
@ -245,33 +257,35 @@ import java.util.UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DrmSessionException getError() {
|
||||
public final @Nullable DrmSessionException getError() {
|
||||
return state == STATE_ERROR ? lastException : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T getMediaCrypto() {
|
||||
public final @Nullable T getMediaCrypto() {
|
||||
return mediaCrypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> queryKeyStatus() {
|
||||
public @Nullable Map<String, String> queryKeyStatus() {
|
||||
return sessionId == null ? null : mediaDrm.queryKeyStatus(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getOfflineLicenseKeySetId() {
|
||||
public @Nullable byte[] getOfflineLicenseKeySetId() {
|
||||
return offlineLicenseKeySetId;
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
/**
|
||||
* Try to open a session, do provisioning if necessary.
|
||||
* @param allowProvisioning if provisioning is allowed, set this to false when calling from
|
||||
* processing provision response.
|
||||
* @return true on success, false otherwise.
|
||||
* Try to open a session, do provisioning if necessary.
|
||||
*
|
||||
* @param allowProvisioning if provisioning is allowed, set this to false when calling from
|
||||
* processing provision response.
|
||||
* @return true on success, false otherwise.
|
||||
*/
|
||||
@EnsuresNonNullIf(result = true, expression = "sessionId")
|
||||
private boolean openInternal(boolean allowProvisioning) {
|
||||
if (isOpen()) {
|
||||
// Already opened
|
||||
@ -319,19 +333,20 @@ import java.util.UUID;
|
||||
provisioningManager.onProvisionCompleted();
|
||||
}
|
||||
|
||||
@RequiresNonNull("sessionId")
|
||||
private void doLicense(boolean allowRetry) {
|
||||
switch (mode) {
|
||||
case DefaultDrmSessionManager.MODE_PLAYBACK:
|
||||
case DefaultDrmSessionManager.MODE_QUERY:
|
||||
if (offlineLicenseKeySetId == null) {
|
||||
postKeyRequest(ExoMediaDrm.KEY_TYPE_STREAMING, allowRetry);
|
||||
postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_STREAMING, allowRetry);
|
||||
} else if (state == STATE_OPENED_WITH_KEYS || restoreKeys()) {
|
||||
long licenseDurationRemainingSec = getLicenseDurationRemainingSec();
|
||||
if (mode == DefaultDrmSessionManager.MODE_PLAYBACK
|
||||
&& licenseDurationRemainingSec <= MAX_LICENSE_DURATION_TO_RENEW) {
|
||||
Log.d(TAG, "Offline license has expired or will expire soon. "
|
||||
+ "Remaining seconds: " + licenseDurationRemainingSec);
|
||||
postKeyRequest(ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
} else if (licenseDurationRemainingSec <= 0) {
|
||||
onError(new KeysExpiredException());
|
||||
} else {
|
||||
@ -342,19 +357,20 @@ import java.util.UUID;
|
||||
break;
|
||||
case DefaultDrmSessionManager.MODE_DOWNLOAD:
|
||||
if (offlineLicenseKeySetId == null) {
|
||||
postKeyRequest(ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
} else {
|
||||
// Renew
|
||||
if (restoreKeys()) {
|
||||
postKeyRequest(ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DefaultDrmSessionManager.MODE_RELEASE:
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
// It's not necessary to restore the key (and open a session to do that) before releasing it
|
||||
// but this serves as a good sanity/fast-failure check.
|
||||
if (restoreKeys()) {
|
||||
postKeyRequest(ExoMediaDrm.KEY_TYPE_RELEASE, allowRetry);
|
||||
postKeyRequest(offlineLicenseKeySetId, ExoMediaDrm.KEY_TYPE_RELEASE, allowRetry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -362,6 +378,7 @@ import java.util.UUID;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresNonNull({"sessionId", "offlineLicenseKeySetId"})
|
||||
private boolean restoreKeys() {
|
||||
try {
|
||||
mediaDrm.restoreKeys(sessionId, offlineLicenseKeySetId);
|
||||
@ -377,12 +394,12 @@ import java.util.UUID;
|
||||
if (!C.WIDEVINE_UUID.equals(uuid)) {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
Pair<Long, Long> pair = WidevineUtil.getLicenseDurationRemainingSec(this);
|
||||
Pair<Long, Long> pair =
|
||||
Assertions.checkNotNull(WidevineUtil.getLicenseDurationRemainingSec(this));
|
||||
return Math.min(pair.first, pair.second);
|
||||
}
|
||||
|
||||
private void postKeyRequest(int type, boolean allowRetry) {
|
||||
byte[] scope = type == ExoMediaDrm.KEY_TYPE_RELEASE ? offlineLicenseKeySetId : sessionId;
|
||||
private void postKeyRequest(byte[] scope, int type, boolean allowRetry) {
|
||||
try {
|
||||
currentKeyRequest =
|
||||
mediaDrm.getKeyRequest(scope, schemeDatas, type, optionalKeyRequestParameters);
|
||||
@ -407,7 +424,7 @@ import java.util.UUID;
|
||||
try {
|
||||
byte[] responseData = (byte[]) response;
|
||||
if (mode == DefaultDrmSessionManager.MODE_RELEASE) {
|
||||
mediaDrm.provideKeyResponse(offlineLicenseKeySetId, responseData);
|
||||
mediaDrm.provideKeyResponse(Util.castNonNull(offlineLicenseKeySetId), responseData);
|
||||
eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmKeysRestored);
|
||||
} else {
|
||||
byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData);
|
||||
@ -447,6 +464,8 @@ import java.util.UUID;
|
||||
}
|
||||
}
|
||||
|
||||
@EnsuresNonNullIf(result = true, expression = "sessionId")
|
||||
@SuppressWarnings("contracts.conditional.postcondition.not.satisfied")
|
||||
private boolean isOpen() {
|
||||
return state == STATE_OPENED || state == STATE_OPENED_WITH_KEYS;
|
||||
}
|
||||
@ -461,8 +480,9 @@ import java.util.UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleMessage(Message msg) {
|
||||
Pair<?, ?> requestAndResponse = (Pair<?, ?>) msg.obj;
|
||||
Pair<Object, Object> requestAndResponse = (Pair<Object, Object>) msg.obj;
|
||||
Object request = requestAndResponse.first;
|
||||
Object response = requestAndResponse.second;
|
||||
switch (msg.what) {
|
||||
|
@ -21,7 +21,7 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSession.ProvisioningManager;
|
||||
@ -94,7 +94,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
private final UUID uuid;
|
||||
private final ExoMediaDrm<T> mediaDrm;
|
||||
private final MediaDrmCallback callback;
|
||||
private final HashMap<String, String> optionalKeyRequestParameters;
|
||||
private final @Nullable HashMap<String, String> optionalKeyRequestParameters;
|
||||
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
|
||||
private final boolean multiSession;
|
||||
private final int initialDrmRequestRetryCount;
|
||||
@ -102,11 +102,11 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
private final List<DefaultDrmSession<T>> sessions;
|
||||
private final List<DefaultDrmSession<T>> provisioningSessions;
|
||||
|
||||
private Looper playbackLooper;
|
||||
private @Nullable Looper playbackLooper;
|
||||
private int mode;
|
||||
private byte[] offlineLicenseKeySetId;
|
||||
private @Nullable byte[] offlineLicenseKeySetId;
|
||||
|
||||
/* package */ volatile MediaDrmHandler mediaDrmHandler;
|
||||
/* package */ volatile @Nullable MediaDrmHandler mediaDrmHandler;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #newWidevineInstance(MediaDrmCallback, HashMap)} and {@link
|
||||
@ -115,9 +115,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
@Deprecated
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newWidevineInstance(
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener)
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener)
|
||||
throws UnsupportedDrmException {
|
||||
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
||||
newWidevineInstance(callback, optionalKeyRequestParameters);
|
||||
@ -136,7 +136,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* @throws UnsupportedDrmException If the specified DRM scheme is not supported.
|
||||
*/
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newWidevineInstance(
|
||||
MediaDrmCallback callback, HashMap<String, String> optionalKeyRequestParameters)
|
||||
MediaDrmCallback callback, @Nullable HashMap<String, String> optionalKeyRequestParameters)
|
||||
throws UnsupportedDrmException {
|
||||
return newFrameworkInstance(C.WIDEVINE_UUID, callback, optionalKeyRequestParameters);
|
||||
}
|
||||
@ -148,9 +148,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
@Deprecated
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newPlayReadyInstance(
|
||||
MediaDrmCallback callback,
|
||||
String customData,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener)
|
||||
@Nullable String customData,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener)
|
||||
throws UnsupportedDrmException {
|
||||
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
||||
newPlayReadyInstance(callback, customData);
|
||||
@ -171,7 +171,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* @throws UnsupportedDrmException If the specified DRM scheme is not supported.
|
||||
*/
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newPlayReadyInstance(
|
||||
MediaDrmCallback callback, String customData) throws UnsupportedDrmException {
|
||||
MediaDrmCallback callback, @Nullable String customData) throws UnsupportedDrmException {
|
||||
HashMap<String, String> optionalKeyRequestParameters;
|
||||
if (!TextUtils.isEmpty(customData)) {
|
||||
optionalKeyRequestParameters = new HashMap<>();
|
||||
@ -190,9 +190,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newFrameworkInstance(
|
||||
UUID uuid,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener)
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener)
|
||||
throws UnsupportedDrmException {
|
||||
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
||||
newFrameworkInstance(uuid, callback, optionalKeyRequestParameters);
|
||||
@ -212,7 +212,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* @throws UnsupportedDrmException If the specified DRM scheme is not supported.
|
||||
*/
|
||||
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newFrameworkInstance(
|
||||
UUID uuid, MediaDrmCallback callback, HashMap<String, String> optionalKeyRequestParameters)
|
||||
UUID uuid,
|
||||
MediaDrmCallback callback,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters)
|
||||
throws UnsupportedDrmException {
|
||||
return new DefaultDrmSessionManager<>(
|
||||
uuid,
|
||||
@ -228,13 +230,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* and {@link #addListener(Handler, DefaultDrmSessionEventListener)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("method.invocation.invalid")
|
||||
public DefaultDrmSessionManager(
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener) {
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener) {
|
||||
this(uuid, mediaDrm, callback, optionalKeyRequestParameters);
|
||||
if (eventHandler != null && eventListener != null) {
|
||||
addListener(eventHandler, eventListener);
|
||||
@ -252,7 +255,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters) {
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters) {
|
||||
this(
|
||||
uuid,
|
||||
mediaDrm,
|
||||
@ -267,13 +270,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* boolean)} and {@link #addListener(Handler, DefaultDrmSessionEventListener)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("method.invocation.invalid")
|
||||
public DefaultDrmSessionManager(
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener,
|
||||
boolean multiSession) {
|
||||
this(uuid, mediaDrm, callback, optionalKeyRequestParameters, multiSession);
|
||||
if (eventHandler != null && eventListener != null) {
|
||||
@ -294,7 +298,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
boolean multiSession) {
|
||||
this(
|
||||
uuid,
|
||||
@ -310,13 +314,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* boolean, int)} and {@link #addListener(Handler, DefaultDrmSessionEventListener)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("method.invocation.invalid")
|
||||
public DefaultDrmSessionManager(
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
Handler eventHandler,
|
||||
DefaultDrmSessionEventListener eventListener,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable Handler eventHandler,
|
||||
@Nullable DefaultDrmSessionEventListener eventListener,
|
||||
boolean multiSession,
|
||||
int initialDrmRequestRetryCount) {
|
||||
this(
|
||||
@ -346,7 +351,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters,
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters,
|
||||
boolean multiSession,
|
||||
int initialDrmRequestRetryCount) {
|
||||
Assertions.checkNotNull(uuid);
|
||||
@ -443,21 +448,22 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
* required.
|
||||
*
|
||||
* <p>{@code mode} must be one of these:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #MODE_PLAYBACK}: If {@code offlineLicenseKeySetId} is null, a streaming license is
|
||||
* requested otherwise the offline license is restored.
|
||||
* <li>{@link #MODE_QUERY}: {@code offlineLicenseKeySetId} can not be null. The offline license
|
||||
* is restored.
|
||||
* <li>{@link #MODE_DOWNLOAD}: If {@code offlineLicenseKeySetId} is null, an offline license is
|
||||
* requested otherwise the offline license is renewed.
|
||||
* <li>{@link #MODE_RELEASE}: {@code offlineLicenseKeySetId} can not be null. The offline license
|
||||
* is released.
|
||||
* <li>{@link #MODE_PLAYBACK}: If {@code offlineLicenseKeySetId} is null, a streaming license is
|
||||
* requested otherwise the offline license is restored.
|
||||
* <li>{@link #MODE_QUERY}: {@code offlineLicenseKeySetId} can not be null. The offline license
|
||||
* is restored.
|
||||
* <li>{@link #MODE_DOWNLOAD}: If {@code offlineLicenseKeySetId} is null, an offline license is
|
||||
* requested otherwise the offline license is renewed.
|
||||
* <li>{@link #MODE_RELEASE}: {@code offlineLicenseKeySetId} can not be null. The offline
|
||||
* license is released.
|
||||
* </ul>
|
||||
*
|
||||
* @param mode The mode to be set.
|
||||
* @param offlineLicenseKeySetId The key set id of the license to be used with the given mode.
|
||||
*/
|
||||
public void setMode(@Mode int mode, byte[] offlineLicenseKeySetId) {
|
||||
public void setMode(@Mode int mode, @Nullable byte[] offlineLicenseKeySetId) {
|
||||
Assertions.checkState(sessions.isEmpty());
|
||||
if (mode == MODE_QUERY || mode == MODE_RELEASE) {
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
@ -469,7 +475,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
// DrmSessionManager implementation.
|
||||
|
||||
@Override
|
||||
public boolean canAcquireSession(@NonNull DrmInitData drmInitData) {
|
||||
public boolean canAcquireSession(DrmInitData drmInitData) {
|
||||
if (offlineLicenseKeySetId != null) {
|
||||
// An offline license can be restored so a session can always be acquired.
|
||||
return true;
|
||||
@ -650,10 +656,14 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
private class MediaDrmEventListener implements OnEventListener<T> {
|
||||
|
||||
@Override
|
||||
public void onEvent(ExoMediaDrm<? extends T> md, byte[] sessionId, int event, int extra,
|
||||
byte[] data) {
|
||||
public void onEvent(
|
||||
ExoMediaDrm<? extends T> md,
|
||||
byte[] sessionId,
|
||||
int event,
|
||||
int extra,
|
||||
@Nullable byte[] data) {
|
||||
if (mode == DefaultDrmSessionManager.MODE_PLAYBACK) {
|
||||
mediaDrmHandler.obtainMessage(event, sessionId).sendToTarget();
|
||||
Assertions.checkNotNull(mediaDrmHandler).obtainMessage(event, sessionId).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,10 +85,8 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
// Lazily initialized hashcode.
|
||||
private int hashCode;
|
||||
|
||||
/**
|
||||
* The protection scheme type, or null if not applicable or unknown.
|
||||
*/
|
||||
@Nullable public final String schemeType;
|
||||
/** The protection scheme type, or null if not applicable or unknown. */
|
||||
public final @Nullable String schemeType;
|
||||
|
||||
/**
|
||||
* Number of {@link SchemeData}s.
|
||||
@ -106,7 +104,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
* @param schemeType See {@link #schemeType}.
|
||||
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
||||
*/
|
||||
public DrmInitData(String schemeType, List<SchemeData> schemeDatas) {
|
||||
public DrmInitData(@Nullable String schemeType, List<SchemeData> schemeDatas) {
|
||||
this(schemeType, false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
|
||||
}
|
||||
|
||||
@ -131,11 +129,11 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
if (cloneSchemeDatas) {
|
||||
schemeDatas = schemeDatas.clone();
|
||||
}
|
||||
// Sorting ensures that universal scheme data (i.e. data that applies to all schemes) is matched
|
||||
// last. It's also required by the equals and hashcode implementations.
|
||||
Arrays.sort(schemeDatas, this);
|
||||
this.schemeDatas = schemeDatas;
|
||||
schemeDataCount = schemeDatas.length;
|
||||
// Sorting ensures that universal scheme data (i.e. data that applies to all schemes) is matched
|
||||
// last. It's also required by the equals and hashcode implementations.
|
||||
Arrays.sort(this.schemeDatas, this);
|
||||
}
|
||||
|
||||
/* package */ DrmInitData(Parcel in) {
|
||||
@ -152,7 +150,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
* @return The initialization data for the scheme, or null if the scheme is not supported.
|
||||
*/
|
||||
@Deprecated
|
||||
public SchemeData get(UUID uuid) {
|
||||
public @Nullable SchemeData get(UUID uuid) {
|
||||
for (SchemeData schemeData : schemeDatas) {
|
||||
if (schemeData.matches(uuid)) {
|
||||
return schemeData;
|
||||
@ -270,10 +268,8 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
public final @Nullable String licenseServerUrl;
|
||||
/** The mimeType of {@link #data}. */
|
||||
public final String mimeType;
|
||||
/**
|
||||
* The initialization data. May be null for scheme support checks only.
|
||||
*/
|
||||
public final byte[] data;
|
||||
/** The initialization data. May be null for scheme support checks only. */
|
||||
public final @Nullable byte[] data;
|
||||
/**
|
||||
* Whether secure decryption is required.
|
||||
*/
|
||||
@ -285,7 +281,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
* @param mimeType See {@link #mimeType}.
|
||||
* @param data See {@link #data}.
|
||||
*/
|
||||
public SchemeData(UUID uuid, String mimeType, byte[] data) {
|
||||
public SchemeData(UUID uuid, String mimeType, @Nullable byte[] data) {
|
||||
this(uuid, mimeType, data, false);
|
||||
}
|
||||
|
||||
@ -296,7 +292,8 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
* @param data See {@link #data}.
|
||||
* @param requiresSecureDecryption See {@link #requiresSecureDecryption}.
|
||||
*/
|
||||
public SchemeData(UUID uuid, String mimeType, byte[] data, boolean requiresSecureDecryption) {
|
||||
public SchemeData(
|
||||
UUID uuid, String mimeType, @Nullable byte[] data, boolean requiresSecureDecryption) {
|
||||
this(uuid, /* licenseServerUrl= */ null, mimeType, data, requiresSecureDecryption);
|
||||
}
|
||||
|
||||
@ -312,7 +309,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
UUID uuid,
|
||||
@Nullable String licenseServerUrl,
|
||||
String mimeType,
|
||||
byte[] data,
|
||||
@Nullable byte[] data,
|
||||
boolean requiresSecureDecryption) {
|
||||
this.uuid = Assertions.checkNotNull(uuid);
|
||||
this.licenseServerUrl = licenseServerUrl;
|
||||
@ -324,7 +321,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||
/* package */ SchemeData(Parcel in) {
|
||||
uuid = new UUID(in.readLong(), in.readLong());
|
||||
licenseServerUrl = in.readString();
|
||||
mimeType = in.readString();
|
||||
mimeType = Util.castNonNull(in.readString());
|
||||
data = in.createByteArray();
|
||||
requiresSecureDecryption = in.readByte() != 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm;
|
||||
import android.annotation.TargetApi;
|
||||
import android.media.MediaDrm;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Map;
|
||||
@ -75,21 +76,24 @@ public interface DrmSession<T extends ExoMediaCrypto> {
|
||||
@State int getState();
|
||||
|
||||
/**
|
||||
* Returns the cause of the error state.
|
||||
* Returns the cause of the error state, or null if {@link #getState()} is not {@link
|
||||
* #STATE_ERROR}.
|
||||
*/
|
||||
@Nullable
|
||||
DrmSessionException getError();
|
||||
|
||||
/**
|
||||
* Returns a {@link ExoMediaCrypto} for the open session, or null if called before the session has
|
||||
* been opened or after it's been released.
|
||||
*/
|
||||
@Nullable
|
||||
T getMediaCrypto();
|
||||
|
||||
/**
|
||||
* Returns a map describing the key status for the session, or null if called before the session
|
||||
* has been opened or after it's been released.
|
||||
* <p>
|
||||
* Since DRM license policies vary by vendor, the specific status field names are determined by
|
||||
*
|
||||
* <p>Since DRM license policies vary by vendor, the specific status field names are determined by
|
||||
* each DRM vendor. Refer to your DRM provider documentation for definitions of the field names
|
||||
* for a particular DRM engine plugin.
|
||||
*
|
||||
@ -97,12 +101,13 @@ public interface DrmSession<T extends ExoMediaCrypto> {
|
||||
* has been opened or after it's been released.
|
||||
* @see MediaDrm#queryKeyStatus(byte[])
|
||||
*/
|
||||
@Nullable
|
||||
Map<String, String> queryKeyStatus();
|
||||
|
||||
/**
|
||||
* Returns the key set id of the offline license loaded into this session, or null if there isn't
|
||||
* one.
|
||||
*/
|
||||
@Nullable
|
||||
byte[] getOfflineLicenseKeySetId();
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.drm;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.util.Map;
|
||||
|
||||
@ -33,22 +34,22 @@ public final class ErrorStateDrmSession<T extends ExoMediaCrypto> implements Drm
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrmSessionException getError() {
|
||||
public @Nullable DrmSessionException getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getMediaCrypto() {
|
||||
public @Nullable T getMediaCrypto() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> queryKeyStatus() {
|
||||
public @Nullable Map<String, String> queryKeyStatus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getOfflineLicenseKeySetId() {
|
||||
public @Nullable byte[] getOfflineLicenseKeySetId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
|
||||
String mimeType = null;
|
||||
if (schemeDatas != null) {
|
||||
schemeData = getSchemeData(uuid, schemeDatas);
|
||||
initData = adjustRequestInitData(uuid, schemeData.data);
|
||||
initData = adjustRequestInitData(uuid, Assertions.checkNotNull(schemeData.data));
|
||||
mimeType = adjustRequestMimeType(uuid, schemeData.mimeType);
|
||||
}
|
||||
MediaDrm.KeyRequest request =
|
||||
@ -229,11 +229,12 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
|
||||
boolean canConcatenateData = true;
|
||||
for (int i = 0; i < schemeDatas.size(); i++) {
|
||||
SchemeData schemeData = schemeDatas.get(i);
|
||||
byte[] schemeDataData = Util.castNonNull(schemeData.data);
|
||||
if (schemeData.requiresSecureDecryption == firstSchemeData.requiresSecureDecryption
|
||||
&& Util.areEqual(schemeData.mimeType, firstSchemeData.mimeType)
|
||||
&& Util.areEqual(schemeData.licenseServerUrl, firstSchemeData.licenseServerUrl)
|
||||
&& PsshAtomUtil.isPsshAtom(schemeData.data)) {
|
||||
concatenatedDataLength += schemeData.data.length;
|
||||
&& PsshAtomUtil.isPsshAtom(schemeDataData)) {
|
||||
concatenatedDataLength += schemeDataData.length;
|
||||
} else {
|
||||
canConcatenateData = false;
|
||||
break;
|
||||
@ -244,9 +245,10 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
|
||||
int concatenatedDataPosition = 0;
|
||||
for (int i = 0; i < schemeDatas.size(); i++) {
|
||||
SchemeData schemeData = schemeDatas.get(i);
|
||||
int schemeDataLength = schemeData.data.length;
|
||||
byte[] schemeDataData = Util.castNonNull(schemeData.data);
|
||||
int schemeDataLength = schemeDataData.length;
|
||||
System.arraycopy(
|
||||
schemeData.data, 0, concatenatedData, concatenatedDataPosition, schemeDataLength);
|
||||
schemeDataData, 0, concatenatedData, concatenatedDataPosition, schemeDataLength);
|
||||
concatenatedDataPosition += schemeDataLength;
|
||||
}
|
||||
return firstSchemeData.copyWithData(concatenatedData);
|
||||
@ -257,7 +259,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
|
||||
// the first V0 box.
|
||||
for (int i = 0; i < schemeDatas.size(); i++) {
|
||||
SchemeData schemeData = schemeDatas.get(i);
|
||||
int version = PsshAtomUtil.parseVersion(schemeData.data);
|
||||
int version = PsshAtomUtil.parseVersion(Util.castNonNull(schemeData.data));
|
||||
if (Util.SDK_INT < 23 && version == 0) {
|
||||
return schemeData;
|
||||
} else if (Util.SDK_INT >= 23 && version == 1) {
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
|
||||
@ -135,8 +136,12 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
||||
return executePost(dataSourceFactory, url, request.getData(), requestProperties);
|
||||
}
|
||||
|
||||
private static byte[] executePost(HttpDataSource.Factory dataSourceFactory, String url,
|
||||
byte[] data, Map<String, String> requestProperties) throws IOException {
|
||||
private static byte[] executePost(
|
||||
HttpDataSource.Factory dataSourceFactory,
|
||||
String url,
|
||||
byte[] data,
|
||||
@Nullable Map<String, String> requestProperties)
|
||||
throws IOException {
|
||||
HttpDataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (requestProperties != null) {
|
||||
for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) {
|
||||
@ -164,17 +169,18 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
||||
boolean manuallyRedirect =
|
||||
(e.responseCode == 307 || e.responseCode == 308)
|
||||
&& manualRedirectCount++ < MAX_MANUAL_REDIRECTS;
|
||||
url = manuallyRedirect ? getRedirectUrl(e) : null;
|
||||
if (url == null) {
|
||||
String redirectUrl = manuallyRedirect ? getRedirectUrl(e) : null;
|
||||
if (redirectUrl == null) {
|
||||
throw e;
|
||||
}
|
||||
url = redirectUrl;
|
||||
} finally {
|
||||
Util.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getRedirectUrl(InvalidResponseCodeException exception) {
|
||||
private static @Nullable String getRedirectUrl(InvalidResponseCodeException exception) {
|
||||
Map<String, List<String>> headerFields = exception.headerFields;
|
||||
if (headerFields != null) {
|
||||
List<String> locationHeaders = headerFields.get("Location");
|
||||
|
@ -19,6 +19,7 @@ import android.media.MediaDrm;
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Pair;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
|
||||
@ -34,6 +35,8 @@ import java.util.UUID;
|
||||
*/
|
||||
public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
|
||||
private static final DrmInitData DUMMY_DRM_INIT_DATA = new DrmInitData();
|
||||
|
||||
private final ConditionVariable conditionVariable;
|
||||
private final DefaultDrmSessionManager<T> drmSessionManager;
|
||||
private final HandlerThread handlerThread;
|
||||
@ -95,7 +98,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
String defaultLicenseUrl,
|
||||
boolean forceDefaultLicenseUrl,
|
||||
Factory httpDataSourceFactory,
|
||||
HashMap<String, String> optionalKeyRequestParameters)
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters)
|
||||
throws UnsupportedDrmException {
|
||||
return new OfflineLicenseHelper<>(C.WIDEVINE_UUID,
|
||||
FrameworkMediaDrm.newInstance(C.WIDEVINE_UUID),
|
||||
@ -118,7 +121,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
UUID uuid,
|
||||
ExoMediaDrm<T> mediaDrm,
|
||||
MediaDrmCallback callback,
|
||||
HashMap<String, String> optionalKeyRequestParameters) {
|
||||
@Nullable HashMap<String, String> optionalKeyRequestParameters) {
|
||||
handlerThread = new HandlerThread("OfflineLicenseHelper");
|
||||
handlerThread.start();
|
||||
conditionVariable = new ConditionVariable();
|
||||
@ -199,7 +202,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
public synchronized byte[] renewLicense(byte[] offlineLicenseKeySetId)
|
||||
throws DrmSessionException {
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, offlineLicenseKeySetId, null);
|
||||
return blockingKeyRequest(
|
||||
DefaultDrmSessionManager.MODE_DOWNLOAD, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,7 +215,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
public synchronized void releaseLicense(byte[] offlineLicenseKeySetId)
|
||||
throws DrmSessionException {
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
blockingKeyRequest(DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, null);
|
||||
blockingKeyRequest(
|
||||
DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,8 +229,9 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
|
||||
throws DrmSessionException {
|
||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||
DrmSession<T> drmSession = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY,
|
||||
offlineLicenseKeySetId, null);
|
||||
DrmSession<T> drmSession =
|
||||
openBlockingKeyRequest(
|
||||
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
|
||||
DrmSessionException error = drmSession.getError();
|
||||
Pair<Long, Long> licenseDurationRemainingSec =
|
||||
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
|
||||
@ -236,7 +242,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return licenseDurationRemainingSec;
|
||||
return Assertions.checkNotNull(licenseDurationRemainingSec);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,8 +252,9 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
handlerThread.quit();
|
||||
}
|
||||
|
||||
private byte[] blockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId,
|
||||
DrmInitData drmInitData) throws DrmSessionException {
|
||||
private byte[] blockingKeyRequest(
|
||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
|
||||
throws DrmSessionException {
|
||||
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
|
||||
drmInitData);
|
||||
DrmSessionException error = drmSession.getError();
|
||||
@ -256,11 +263,11 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
if (error != null) {
|
||||
throw error;
|
||||
}
|
||||
return keySetId;
|
||||
return Assertions.checkNotNull(keySetId);
|
||||
}
|
||||
|
||||
private DrmSession<T> openBlockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId,
|
||||
DrmInitData drmInitData) {
|
||||
private DrmSession<T> openBlockingKeyRequest(
|
||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) {
|
||||
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
||||
conditionVariable.close();
|
||||
DrmSession<T> drmSession = drmSessionManager.acquireSession(handlerThread.getLooper(),
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.drm;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Pair;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.util.Map;
|
||||
@ -38,7 +39,8 @@ public final class WidevineUtil {
|
||||
* @return A {@link Pair} consisting of the remaining license and playback durations in seconds,
|
||||
* or null if called before the session has been opened or after it's been released.
|
||||
*/
|
||||
public static Pair<Long, Long> getLicenseDurationRemainingSec(DrmSession<?> drmSession) {
|
||||
public static @Nullable Pair<Long, Long> getLicenseDurationRemainingSec(
|
||||
DrmSession<?> drmSession) {
|
||||
Map<String, String> keyStatus = drmSession.queryKeyStatus();
|
||||
if (keyStatus == null) {
|
||||
return null;
|
||||
|
@ -92,9 +92,12 @@ public class OfflineLicenseHelperTest {
|
||||
public void testDownloadLicenseFailsIfNoKeySetIdIsReturned() throws Exception {
|
||||
setStubLicenseAndPlaybackDurationValues(1000, 200);
|
||||
|
||||
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
|
||||
|
||||
assertThat(offlineLicenseKeySetId).isNull();
|
||||
try {
|
||||
offlineLicenseHelper.downloadLicense(newDrmInitData());
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user