Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bca5254 authored by Jeff Tinker's avatar Jeff Tinker
Browse files

Revert "Revert "Fix MediaDrm security level APIs""

This reverts commit fda717d5.

Change-Id: I5e51c7e8d7ab0626fdfd9726278cb762b79a512e
parent fda717d5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+64 −32
Original line number Diff line number Diff line
@@ -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
@@ -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;

    /**
     * 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;

    /**
     * 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
     */
+27 −40
Original line number Diff line number Diff line
@@ -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 },