Commit 13889c91 by olly Committed by Oliver Woodman

Pass multiple PSSH boxes to Widevine CDM

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=210551848
parent 6b9e1824
......@@ -31,7 +31,9 @@ import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
import com.google.android.exoplayer2.util.EventDispatcher;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
......@@ -76,9 +78,11 @@ import java.util.UUID;
private static final int MSG_KEYS = 1;
private static final int MAX_LICENSE_DURATION_TO_RENEW = 60;
/** The DRM scheme datas, or null if this session uses offline keys. */
public final @Nullable List<SchemeData> schemeDatas;
private final ExoMediaDrm<T> mediaDrm;
private final ProvisioningManager<T> provisioningManager;
private final SchemeData schemeData;
private final @DefaultDrmSessionManager.Mode int mode;
private final HashMap<String, String> optionalKeyRequestParameters;
private final EventDispatcher<DefaultDrmSessionEventListener> eventDispatcher;
......@@ -95,10 +99,10 @@ import java.util.UUID;
private T mediaCrypto;
private DrmSessionException lastException;
private byte[] sessionId;
private byte[] offlineLicenseKeySetId;
private @Nullable byte[] offlineLicenseKeySetId;
private Object currentKeyRequest;
private Object currentProvisionRequest;
private KeyRequest currentKeyRequest;
private ProvisionRequest currentProvisionRequest;
/**
* Instantiates a new DRM session.
......@@ -106,8 +110,8 @@ import java.util.UUID;
* @param uuid The UUID of the drm scheme.
* @param mediaDrm The media DRM.
* @param provisioningManager The manager for provisioning.
* @param schemeData The DRM data for this session, or null if a {@code offlineLicenseKeySetId} is
* provided.
* @param schemeDatas DRM scheme datas for this session, or null if an {@code
* offlineLicenseKeySetId} is provided.
* @param mode The DRM mode.
* @param offlineLicenseKeySetId The offline license key set identifier, or null when not using
* offline keys.
......@@ -122,7 +126,7 @@ import java.util.UUID;
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ProvisioningManager<T> provisioningManager,
@Nullable SchemeData schemeData,
@Nullable List<SchemeData> schemeDatas,
@DefaultDrmSessionManager.Mode int mode,
@Nullable byte[] offlineLicenseKeySetId,
HashMap<String, String> optionalKeyRequestParameters,
......@@ -135,7 +139,8 @@ import java.util.UUID;
this.mediaDrm = mediaDrm;
this.mode = mode;
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
this.schemeData = offlineLicenseKeySetId == null ? schemeData : null;
this.schemeDatas =
offlineLicenseKeySetId == null ? Collections.unmodifiableList(schemeDatas) : null;
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
this.callback = callback;
this.initialDrmRequestRetryCount = initialDrmRequestRetryCount;
......@@ -185,10 +190,6 @@ import java.util.UUID;
return false;
}
public boolean hasInitData(byte[] initData) {
return Arrays.equals(schemeData != null ? schemeData.data : null, initData);
}
public boolean hasSessionId(byte[] sessionId) {
return Arrays.equals(this.sessionId, sessionId);
}
......@@ -380,18 +381,9 @@ import java.util.UUID;
private void postKeyRequest(int type, boolean allowRetry) {
byte[] scope = type == ExoMediaDrm.KEY_TYPE_RELEASE ? offlineLicenseKeySetId : sessionId;
byte[] initData = null;
String mimeType = null;
String licenseServerUrl = null;
if (schemeData != null) {
initData = schemeData.data;
mimeType = schemeData.mimeType;
licenseServerUrl = schemeData.licenseServerUrl;
}
try {
KeyRequest mediaDrmKeyRequest =
mediaDrm.getKeyRequest(scope, initData, mimeType, type, optionalKeyRequestParameters);
currentKeyRequest = Pair.create(mediaDrmKeyRequest, licenseServerUrl);
currentKeyRequest =
mediaDrm.getKeyRequest(scope, schemeDatas, type, optionalKeyRequestParameters);
postRequestHandler.post(MSG_KEYS, currentKeyRequest, allowRetry);
} catch (Exception e) {
onKeysError(e);
......@@ -510,10 +502,7 @@ import java.util.UUID;
response = callback.executeProvisionRequest(uuid, (ProvisionRequest) request);
break;
case MSG_KEYS:
Pair<KeyRequest, String> keyRequest = (Pair<KeyRequest, String>) request;
KeyRequest mediaDrmKeyRequest = keyRequest.first;
String licenseServerUrl = keyRequest.second;
response = callback.executeKeyRequest(uuid, mediaDrmKeyRequest, licenseServerUrl);
response = callback.executeKeyRequest(uuid, (KeyRequest) request);
break;
default:
throw new RuntimeException();
......
......@@ -29,7 +29,6 @@ import com.google.android.exoplayer2.drm.DefaultDrmSession.ProvisioningManager;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener;
import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventDispatcher;
import com.google.android.exoplayer2.util.Util;
......@@ -133,7 +132,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
*
* @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[], byte[], String, int, HashMap)}. May be null.
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
* @throws UnsupportedDrmException If the specified DRM scheme is not supported.
*/
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newWidevineInstance(
......@@ -209,7 +208,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
* @param uuid The UUID of the drm scheme.
* @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[], byte[], String, int, HashMap)}. May be null.
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
* @throws UnsupportedDrmException If the specified DRM scheme is not supported.
*/
public static DefaultDrmSessionManager<FrameworkMediaCrypto> newFrameworkInstance(
......@@ -247,7 +246,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
* @param mediaDrm 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[], byte[], String, int, HashMap)}. May be null.
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
*/
public DefaultDrmSessionManager(
UUID uuid,
......@@ -287,7 +286,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
* @param mediaDrm 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[], byte[], String, int, HashMap)}. May be null.
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
* @param multiSession A boolean that specify whether multiple key session support is enabled.
* Default is false.
*/
......@@ -337,7 +336,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
* @param mediaDrm 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[], byte[], String, int, HashMap)}. May be null.
* to {@link ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null.
* @param multiSession A boolean that specify whether multiple key session support is enabled.
* Default is false.
* @param initialDrmRequestRetryCount The number of times to retry for initial provisioning and
......@@ -475,8 +474,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
// An offline license can be restored so a session can always be acquired.
return true;
}
SchemeData schemeData = getSchemeData(drmInitData, uuid, true);
if (schemeData == null) {
List<SchemeData> schemeDatas = getSchemeDatas(drmInitData, uuid, true);
if (schemeDatas.isEmpty()) {
if (drmInitData.schemeDataCount == 1 && drmInitData.get(0).matches(C.COMMON_PSSH_UUID)) {
// Assume scheme specific data will be added before the session is opened.
Log.w(
......@@ -510,10 +509,10 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
}
}
SchemeData schemeData = null;
List<SchemeData> schemeDatas = null;
if (offlineLicenseKeySetId == null) {
schemeData = getSchemeData(drmInitData, uuid, false);
if (schemeData == null) {
schemeDatas = getSchemeDatas(drmInitData, uuid, false);
if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
return new ErrorStateDrmSession<>(new DrmSessionException(error));
......@@ -526,9 +525,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
} else {
// Only use an existing session if it has matching init data.
session = null;
byte[] initData = schemeData != null ? schemeData.data : null;
for (DefaultDrmSession<T> existingSession : sessions) {
if (existingSession.hasInitData(initData)) {
if (Util.areEqual(existingSession.schemeDatas, schemeDatas)) {
session = existingSession;
break;
}
......@@ -542,7 +540,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
uuid,
mediaDrm,
this,
schemeData,
schemeDatas,
mode,
offlineLicenseKeySetId,
optionalKeyRequestParameters,
......@@ -605,16 +603,17 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
// Internal methods.
/**
* Extracts {@link SchemeData} suitable for the given DRM scheme {@link UUID}.
* Extracts {@link SchemeData} instances suitable for the given DRM scheme {@link UUID}.
*
* @param drmInitData The {@link DrmInitData} from which to extract the {@link SchemeData}.
* @param uuid The UUID.
* @param allowMissingData Whether a {@link SchemeData} with null {@link SchemeData#data} may be
* returned.
* @return The extracted {@link SchemeData}, or null if no suitable data is present.
* @return The extracted {@link SchemeData} instances, or an empty list if no suitable data is
* present.
*/
private static SchemeData getSchemeData(DrmInitData drmInitData, UUID uuid,
boolean allowMissingData) {
private static List<SchemeData> getSchemeDatas(
DrmInitData drmInitData, UUID uuid, boolean allowMissingData) {
// Look for matching scheme data (matching the Common PSSH box for ClearKey).
List<SchemeData> matchingSchemeDatas = new ArrayList<>(drmInitData.schemeDataCount);
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
......@@ -625,27 +624,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
matchingSchemeDatas.add(schemeData);
}
}
if (matchingSchemeDatas.isEmpty()) {
return null;
}
// For Widevine PSSH boxes, prefer V1 boxes from API 23 and V0 before.
if (C.WIDEVINE_UUID.equals(uuid)) {
for (int i = 0; i < matchingSchemeDatas.size(); i++) {
SchemeData matchingSchemeData = matchingSchemeDatas.get(i);
int version = matchingSchemeData.hasData()
? PsshAtomUtil.parseVersion(matchingSchemeData.data) : -1;
if (Util.SDK_INT < 23 && version == 0) {
return matchingSchemeData;
} else if (Util.SDK_INT >= 23 && version == 1) {
return matchingSchemeData;
}
}
}
// If we don't have any special handling, prefer the first matching scheme data.
return matchingSchemeDatas.get(0);
return matchingSchemeDatas;
}
@SuppressLint("HandlerLeak")
......
......@@ -22,6 +22,7 @@ import android.media.MediaDrmException;
import android.media.NotProvisionedException;
import android.os.Handler;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -130,19 +131,19 @@ public interface ExoMediaDrm<T extends ExoMediaCrypto> {
final class KeyRequest {
private final byte[] data;
private final String defaultUrl;
private final String licenseServerUrl;
public KeyRequest(byte[] data, String defaultUrl) {
public KeyRequest(byte[] data, String licenseServerUrl) {
this.data = data;
this.defaultUrl = defaultUrl;
this.licenseServerUrl = licenseServerUrl;
}
public byte[] getData() {
return data;
}
public String getDefaultUrl() {
return defaultUrl;
public String getLicenseServerUrl() {
return licenseServerUrl;
}
}
......@@ -188,13 +189,29 @@ public interface ExoMediaDrm<T extends ExoMediaCrypto> {
*/
void closeSession(byte[] sessionId);
/** @see MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap) */
/**
* Generates a key request.
*
* @param scope If {@code keyType} is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE},
* the session id that the keys will be provided to. If {@code keyType} is {@link
* #KEY_TYPE_RELEASE}, the keySetId of the keys to release.
* @param schemeDatas If key type is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, a
* list of {@link SchemeData} instances extracted from the media. Null otherwise.
* @param keyType The type of the request. Either {@link #KEY_TYPE_STREAMING} to acquire keys for
* streaming, {@link #KEY_TYPE_OFFLINE} to acquire keys for offline usage, or {@link
* #KEY_TYPE_RELEASE} to release acquired keys. Releasing keys invalidates them for all
* sessions.
* @param optionalParameters Are included in the key request message to allow a client application
* to provide additional message parameters to the server. This may be {@code null} if no
* additional parameters are to be sent.
* @return The generated key request.
* @see MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)
*/
KeyRequest getKeyRequest(
byte[] scope,
byte[] init,
String mimeType,
@Nullable List<SchemeData> schemeDatas,
int keyType,
HashMap<String, String> optionalParameters)
@Nullable HashMap<String, String> optionalParameters)
throws NotProvisionedException;
/** @see MediaDrm#provideKeyResponse(byte[], byte[]) */
......
......@@ -24,7 +24,10 @@ import android.media.MediaDrm;
import android.media.MediaDrmException;
import android.media.NotProvisionedException;
import android.media.UnsupportedSchemeException;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
......@@ -119,44 +122,26 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
@Override
public KeyRequest getKeyRequest(
byte[] scope,
byte[] init,
String mimeType,
@Nullable List<DrmInitData.SchemeData> schemeDatas,
int keyType,
HashMap<String, String> optionalParameters)
throws NotProvisionedException {
SchemeData schemeData = getSchemeData(uuid, schemeDatas);
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
// devices also required data to be extracted from the PSSH atom for PlayReady.
if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
|| (C.PLAYREADY_UUID.equals(uuid)
&& "Amazon".equals(Util.MANUFACTURER)
&& ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
|| "AFTS".equals(Util.MODEL) // Fire TV Gen 2
|| "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(init, uuid);
if (psshData == null) {
// Extraction failed. schemeData isn't a PSSH atom, so leave it unchanged.
} else {
init = psshData;
}
}
byte[] initData = adjustRequestInitData(uuid, schemeData.data);
String mimeType = adjustRequestMimeType(uuid, schemeData.mimeType);
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
if (Util.SDK_INT < 26
&& C.CLEARKEY_UUID.equals(uuid)
&& (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
mimeType = CENC_SCHEME_MIME_TYPE;
}
MediaDrm.KeyRequest request =
mediaDrm.getKeyRequest(scope, initData, mimeType, keyType, optionalParameters);
final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
optionalParameters);
byte[] requestData = adjustRequestData(uuid, request.getData());
byte[] requestData = request.getData();
if (C.CLEARKEY_UUID.equals(uuid)) {
requestData = ClearKeyUtil.adjustRequestData(requestData);
String licenseServerUrl = request.getDefaultUrl();
if (TextUtils.isEmpty(licenseServerUrl) && !TextUtils.isEmpty(schemeData.licenseServerUrl)) {
licenseServerUrl = schemeData.licenseServerUrl;
}
return new KeyRequest(requestData, request.getDefaultUrl());
return new KeyRequest(requestData, licenseServerUrl);
}
@Override
......@@ -226,6 +211,94 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
forceAllowInsecureDecoderComponents);
}
private static SchemeData getSchemeData(UUID uuid, List<SchemeData> schemeDatas) {
if (!C.WIDEVINE_UUID.equals(uuid)) {
// For non-Widevine CDMs always use the first scheme data.
return schemeDatas.get(0);
}
if (Util.SDK_INT >= 28 && schemeDatas.size() > 1) {
// For API level 28 and above, concatenate multiple PSSH scheme datas if possible.
SchemeData firstSchemeData = schemeDatas.get(0);
int concatenatedDataLength = 0;
boolean canConcatenateData = true;
for (int i = 0; i < schemeDatas.size(); i++) {
SchemeData schemeData = schemeDatas.get(i);
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;
} else {
canConcatenateData = false;
break;
}
}
if (canConcatenateData) {
byte[] concatenatedData = new byte[concatenatedDataLength];
int concatenatedDataPosition = 0;
for (int i = 0; i < schemeDatas.size(); i++) {
SchemeData schemeData = schemeDatas.get(i);
int schemeDataLength = schemeData.data.length;
System.arraycopy(
schemeData.data, 0, concatenatedData, concatenatedDataPosition, schemeDataLength);
concatenatedDataPosition += schemeDataLength;
}
return firstSchemeData.copyWithData(concatenatedData);
}
}
// For API levels 23 - 27, prefer the first V1 PSSH box. For API levels 22 and earlier, prefer
// the first V0 box.
for (int i = 0; i < schemeDatas.size(); i++) {
SchemeData schemeData = schemeDatas.get(i);
int version = PsshAtomUtil.parseVersion(schemeData.data);
if (Util.SDK_INT < 23 && version == 0) {
return schemeData;
} else if (Util.SDK_INT >= 23 && version == 1) {
return schemeData;
}
}
// If all else fails, use the first scheme data.
return schemeDatas.get(0);
}
private static byte[] adjustRequestInitData(UUID uuid, byte[] initData) {
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
// devices also required data to be extracted from the PSSH atom for PlayReady.
if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
|| (C.PLAYREADY_UUID.equals(uuid)
&& "Amazon".equals(Util.MANUFACTURER)
&& ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
|| "AFTS".equals(Util.MODEL) // Fire TV Gen 2
|| "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
if (psshData != null) {
// Extraction succeeded, so return the extracted data.
return psshData;
}
}
return initData;
}
private static String adjustRequestMimeType(UUID uuid, String mimeType) {
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
if (Util.SDK_INT < 26
&& C.CLEARKEY_UUID.equals(uuid)
&& (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
return CENC_SCHEME_MIME_TYPE;
}
return mimeType;
}
private static byte[] adjustRequestData(UUID uuid, byte[] requestData) {
if (C.CLEARKEY_UUID.equals(uuid)) {
return ClearKeyUtil.adjustRequestData(requestData);
}
return requestData;
}
@SuppressLint("WrongConstant") // Suppress spurious lint error [Internal ref: b/32137960]
private static void forceWidevineL3(MediaDrm mediaDrm) {
mediaDrm.setPropertyString("securityLevel", "L3");
......
......@@ -17,7 +17,6 @@ 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;
......@@ -115,13 +114,8 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
}
@Override
public byte[] executeKeyRequest(
UUID uuid, KeyRequest request, @Nullable String mediaProvidedLicenseServerUrl)
throws Exception {
String url = request.getDefaultUrl();
if (TextUtils.isEmpty(url)) {
url = mediaProvidedLicenseServerUrl;
}
public byte[] executeKeyRequest(UUID uuid, KeyRequest request) throws Exception {
String url = request.getLicenseServerUrl();
if (forceDefaultLicenseUrl || TextUtils.isEmpty(url)) {
url = defaultLicenseUrl;
}
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.drm;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
import com.google.android.exoplayer2.util.Assertions;
......@@ -45,9 +44,7 @@ public final class LocalMediaDrmCallback implements MediaDrmCallback {
}
@Override
public byte[] executeKeyRequest(
UUID uuid, KeyRequest request, @Nullable String mediaProvidedLicenseServerUrl)
throws Exception {
public byte[] executeKeyRequest(UUID uuid, KeyRequest request) throws Exception {
return keyResponse;
}
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.drm;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
import java.util.UUID;
......@@ -39,13 +38,9 @@ public interface MediaDrmCallback {
* Executes a key request.
*
* @param uuid The UUID of the content protection scheme.
* @param request The request generated by the content decryption module.
* @param mediaProvidedLicenseServerUrl A license server URL provided by the media, or null if the
* media does not include any license server URL.
* @param request The request.
* @return The response data.
* @throws Exception If an error occurred executing the request.
*/
byte[] executeKeyRequest(
UUID uuid, KeyRequest request, @Nullable String mediaProvidedLicenseServerUrl)
throws Exception;
byte[] executeKeyRequest(UUID uuid, KeyRequest request) throws Exception;
}
......@@ -78,6 +78,16 @@ public final class PsshAtomUtil {
}
/**
* Returns whether the data is a valid PSSH atom.
*
* @param data The data to parse.
* @return Whether the data is a valid PSSH atom.
*/
public static boolean isPsshAtom(byte[] data) {
return parsePsshAtom(data) != null;
}
/**
* Parses the UUID from a PSSH atom. Version 0 and 1 PSSH atoms are supported.
*
* <p>The UUID is only parsed if the data is a valid PSSH atom.
......
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