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

Commit ffbc8210 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Fix MediaDrm security level APIs"""

parents df210b43 2bca5254
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 },