Revert "Revert "Fix MediaDrm security level APIs""

This reverts commit fda717d501.

Change-Id: I5e51c7e8d7ab0626fdfd9726278cb762b79a512e
This commit is contained in:
Jeff Tinker
2018-02-11 18:59:14 +00:00
parent fda717d501
commit 2bca525460
3 changed files with 93 additions and 73 deletions

View File

@@ -23371,6 +23371,7 @@ package android.media {
method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
method public int getMaxHdcpLevel();
method public static int getMaxSecurityLevel();
method public int getMaxSessionCount();
method public android.os.PersistableBundle getMetrics();
method public int getOpenSessionCount();
@@ -23384,6 +23385,7 @@ package android.media {
method public static boolean isCryptoSchemeSupported(java.util.UUID);
method public static boolean isCryptoSchemeSupported(java.util.UUID, java.lang.String);
method public byte[] openSession() throws android.media.NotProvisionedException, android.media.ResourceBusyException;
method public byte[] openSession(int) throws android.media.NotProvisionedException, android.media.ResourceBusyException;
method public byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.NotProvisionedException;
method public void provideProvisionResponse(byte[]) throws android.media.DeniedByServerException;
method public java.util.HashMap<java.lang.String, java.lang.String> queryKeyStatus(byte[]);
@@ -23399,7 +23401,6 @@ package android.media {
method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
method public void setPropertyByteArray(java.lang.String, byte[]);
method public void setPropertyString(java.lang.String, java.lang.String);
method public void setSecurityLevel(byte[], int);
field public static final deprecated int EVENT_KEY_EXPIRED = 3; // 0x3
field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1

View File

@@ -634,8 +634,39 @@ public final class MediaDrm implements AutoCloseable {
* @throws ResourceBusyException if required resources are in use
*/
@NonNull
public native byte[] openSession() throws NotProvisionedException,
ResourceBusyException;
public byte[] openSession() throws NotProvisionedException,
ResourceBusyException {
return openSession(getMaxSecurityLevel());
}
/**
* Open a new session at a requested security level. The security level
* represents the robustness of the device's DRM implementation. By default,
* sessions are opened at the native security level of the device.
* Overriding the security level is necessary when the decrypted frames need
* to be manipulated, such as for image compositing. The security level
* parameter must be lower than the native level. Reducing the security
* level will typically limit the content to lower resolutions, as
* determined by the license policy. If the requested level is not
* supported, the next lower supported security level will be set. The level
* can be queried using {@link #getSecurityLevel}. A session
* ID is returned.
*
* @param level the new security level, one of
* {@link #SW_SECURE_CRYPTO}, {@link #SW_SECURE_DECODE},
* {@link #HW_SECURE_CRYPTO}, {@link #HW_SECURE_DECODE} or
* {@link #HW_SECURE_ALL}.
*
* @throws NotProvisionedException if provisioning is needed
* @throws ResourceBusyException if required resources are in use
* @throws IllegalArgumentException if the requested security level is
* higher than the native level or lower than the lowest supported level or
* if the device does not support specifying the security level when opening
* a session
*/
@NonNull
public native byte[] openSession(@SecurityLevel int level) throws
NotProvisionedException, ResourceBusyException;
/**
* Close a session on the MediaDrm object that was previously opened
@@ -1109,7 +1140,7 @@ public final class MediaDrm implements AutoCloseable {
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({SECURITY_LEVEL_UNKNOWN, SW_SECURE_CRYPTO, SW_SECURE_DECODE,
HW_SECURE_CRYPTO, HW_SECURE_DECODE, HW_SECURE_ALL})
HW_SECURE_CRYPTO, HW_SECURE_DECODE, HW_SECURE_ALL})
public @interface SecurityLevel {}
/**
@@ -1119,39 +1150,55 @@ public final class MediaDrm implements AutoCloseable {
public static final int SECURITY_LEVEL_UNKNOWN = 0;
/**
* Software-based whitebox crypto
* DRM key management uses software-based whitebox crypto.
*/
public static final int SW_SECURE_CRYPTO = 1;
/**
* Software-based whitebox crypto and an obfuscated decoder
* DRM key management and decoding use software-based whitebox crypto.
*/
public static final int SW_SECURE_DECODE = 2;
public static final int SW_SECURE_DECODE = 2;
/**
* DRM key management and crypto operations are performed within a
* hardware backed trusted execution environment
* DRM key management and crypto operations are performed within a hardware
* backed trusted execution environment.
*/
public static final int HW_SECURE_CRYPTO = 3;
/**
* DRM key management, crypto operations and decoding of content
* are performed within a hardware backed trusted execution environment
* DRM key management, crypto operations and decoding of content are
* performed within a hardware backed trusted execution environment.
*/
public static final int HW_SECURE_DECODE = 4;
public static final int HW_SECURE_DECODE = 4;
/**
* DRM key management, crypto operations, decoding of content and all
* handling of the media (compressed and uncompressed) is handled within
* a hardware backed trusted execution environment.
* handling of the media (compressed and uncompressed) is handled within a
* hardware backed trusted execution environment.
*/
public static final int HW_SECURE_ALL = 5;
/**
* Return the current security level of a session. A session
* has an initial security level determined by the robustness of
* the DRM system's implementation on the device. The security
* level may be adjusted using {@link #setSecurityLevel}.
* The maximum security level supported by the device. This is the default
* security level when a session is opened.
* @hide
*/
public static final int SECURITY_LEVEL_MAX = 6;
/**
* The maximum security level supported by the device. This is the default
* security level when a session is opened.
*/
@SecurityLevel
public static final int getMaxSecurityLevel() {
return SECURITY_LEVEL_MAX;
}
/**
* Return the current security level of a session. A session has an initial
* security level determined by the robustness of the DRM system's
* implementation on the device. The security level may be changed at the
* time a session is opened using {@link #openSession}.
* @param sessionId the session to query.
* <p>
* @return one of {@link #SECURITY_LEVEL_UNKNOWN},
@@ -1162,21 +1209,6 @@ public final class MediaDrm implements AutoCloseable {
@SecurityLevel
public native int getSecurityLevel(@NonNull byte[] sessionId);
/**
* Set the security level of a session. This can be useful if specific
* attributes of a lower security level are needed by an application,
* such as image manipulation or compositing. Reducing the security
* level will typically limit decryption to lower content resolutions,
* depending on the license policy.
* @param sessionId the session to set the security level on.
* @param level the new security level, one of
* {@link #SW_SECURE_CRYPTO}, {@link #SW_SECURE_DECODE},
* {@link #HW_SECURE_CRYPTO}, {@link #HW_SECURE_DECODE} or
* {@link #HW_SECURE_ALL}.
*/
public native void setSecurityLevel(@NonNull byte[] sessionId,
@SecurityLevel int level);
/**
* String property name: identifies the maker of the DRM plugin
*/

View File

@@ -145,6 +145,7 @@ struct HDCPLevels {
struct SecurityLevels {
jint kSecurityLevelUnknown;
jint kSecurityLevelMax;
jint kSecurityLevelSwSecureCrypto;
jint kSecurityLevelSwSecureDecode;
jint kSecurityLevelHwSecureCrypto;
@@ -683,6 +684,10 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
GET_STATIC_FIELD_ID(field, clazz, "HW_SECURE_ALL", "I");
gSecurityLevels.kSecurityLevelHwSecureAll = env->GetStaticIntField(clazz, field);
jmethodID getMaxSecurityLevel;
GET_STATIC_METHOD_ID(getMaxSecurityLevel, clazz, "getMaxSecurityLevel", "()I");
gSecurityLevels.kSecurityLevelMax = env->CallStaticIntMethod(clazz, getMaxSecurityLevel);
FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
@@ -813,7 +818,7 @@ static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
}
static jbyteArray android_media_MediaDrm_openSession(
JNIEnv *env, jobject thiz) {
JNIEnv *env, jobject thiz, jint jlevel) {
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
@@ -823,7 +828,26 @@ static jbyteArray android_media_MediaDrm_openSession(
}
Vector<uint8_t> sessionId;
status_t err = drm->openSession(sessionId);
DrmPlugin::SecurityLevel level;
if (jlevel == gSecurityLevels.kSecurityLevelMax) {
level = DrmPlugin::kSecurityLevelMax;
} else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureCrypto) {
level = DrmPlugin::kSecurityLevelSwSecureCrypto;
} else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureDecode) {
level = DrmPlugin::kSecurityLevelSwSecureDecode;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureCrypto) {
level = DrmPlugin::kSecurityLevelHwSecureCrypto;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureDecode) {
level = DrmPlugin::kSecurityLevelHwSecureDecode;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureAll) {
level = DrmPlugin::kSecurityLevelHwSecureAll;
} else {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
return NULL;
}
status_t err = drm->openSession(level, sessionId);
if (throwExceptionAsNecessary(env, err, "Failed to open session")) {
return NULL;
@@ -1345,40 +1369,6 @@ static jint android_media_MediaDrm_getSecurityLevel(JNIEnv *env,
}
static void android_media_MediaDrm_setSecurityLevel(JNIEnv *env,
jobject thiz, jbyteArray jsessionId, jint jlevel) {
sp<IDrm> drm = GetDrm(env, thiz);
if (!CheckSession(env, drm, jsessionId)) {
return;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
DrmPlugin::SecurityLevel level;
if (jlevel == gSecurityLevels.kSecurityLevelSwSecureCrypto) {
level = DrmPlugin::kSecurityLevelSwSecureCrypto;
} else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureDecode) {
level = DrmPlugin::kSecurityLevelSwSecureDecode;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureCrypto) {
level = DrmPlugin::kSecurityLevelHwSecureCrypto;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureDecode) {
level = DrmPlugin::kSecurityLevelHwSecureDecode;
} else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureAll) {
level = DrmPlugin::kSecurityLevelHwSecureAll;
} else {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
return;
}
status_t err = drm->setSecurityLevel(sessionId, level);
if (throwExceptionAsNecessary(env, err, "Failed to set security level")) {
return;
}
}
static jstring android_media_MediaDrm_getPropertyString(
JNIEnv *env, jobject thiz, jstring jname) {
sp<IDrm> drm = GetDrm(env, thiz);
@@ -1724,7 +1714,7 @@ static const JNINativeMethod gMethods[] = {
{ "isCryptoSchemeSupportedNative", "([BLjava/lang/String;)Z",
(void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
{ "openSession", "()[B",
{ "openSession", "(I)[B",
(void *)android_media_MediaDrm_openSession },
{ "closeSession", "([B)V",
@@ -1785,9 +1775,6 @@ static const JNINativeMethod gMethods[] = {
{ "getSecurityLevel", "([B)I",
(void *)android_media_MediaDrm_getSecurityLevel },
{ "setSecurityLevel", "([BI)V",
(void *)android_media_MediaDrm_setSecurityLevel },
{ "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)android_media_MediaDrm_getPropertyString },