Support AES-CBC sample encryption in MediaDrm
bug:23719082 Change-Id: I06eb39bd8ad9b55ea0da4011258cac62a8c21ae1
This commit is contained in:
@@ -2175,8 +2175,6 @@ final public class MediaCodec {
|
||||
int offset, int size, long presentationTimeUs, int flags)
|
||||
throws CryptoException;
|
||||
|
||||
// The following mode constants MUST stay in sync with their equivalents
|
||||
// in media/hardware/CryptoAPI.h !
|
||||
public static final int CRYPTO_MODE_UNENCRYPTED = 0;
|
||||
public static final int CRYPTO_MODE_AES_CTR = 1;
|
||||
public static final int CRYPTO_MODE_AES_CBC = 2;
|
||||
|
||||
@@ -85,6 +85,13 @@ static struct {
|
||||
jmethodID setNativeObjectLocked;
|
||||
} gPersistentSurfaceClassInfo;
|
||||
|
||||
static struct {
|
||||
jint Unencrypted;
|
||||
jint AesCtr;
|
||||
jint AesCbc;
|
||||
} gCryptoModes;
|
||||
|
||||
|
||||
struct fields_t {
|
||||
jfieldID context;
|
||||
jmethodID postEventFromNativeID;
|
||||
@@ -94,6 +101,9 @@ struct fields_t {
|
||||
jfieldID cryptoInfoKeyID;
|
||||
jfieldID cryptoInfoIVID;
|
||||
jfieldID cryptoInfoModeID;
|
||||
jfieldID cryptoInfoPatternID;
|
||||
jfieldID patternEncryptBlocksID;
|
||||
jfieldID patternSkipBlocksID;
|
||||
};
|
||||
|
||||
static fields_t gFields;
|
||||
@@ -325,11 +335,12 @@ status_t JMediaCodec::queueSecureInputBuffer(
|
||||
const uint8_t key[16],
|
||||
const uint8_t iv[16],
|
||||
CryptoPlugin::Mode mode,
|
||||
const CryptoPlugin::Pattern &pattern,
|
||||
int64_t presentationTimeUs,
|
||||
uint32_t flags,
|
||||
AString *errorDetailMsg) {
|
||||
return mCodec->queueSecureInputBuffer(
|
||||
index, offset, subSamples, numSubSamples, key, iv, mode,
|
||||
index, offset, subSamples, numSubSamples, key, iv, mode, pattern,
|
||||
presentationTimeUs, flags, errorDetailMsg);
|
||||
}
|
||||
|
||||
@@ -1275,7 +1286,26 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
|
||||
jbyteArray ivObj =
|
||||
(jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
|
||||
|
||||
jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
|
||||
jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
|
||||
enum CryptoPlugin::Mode mode;
|
||||
if (jmode == gCryptoModes.Unencrypted) {
|
||||
mode = CryptoPlugin::kMode_Unencrypted;
|
||||
} else if (jmode == gCryptoModes.AesCtr) {
|
||||
mode = CryptoPlugin::kMode_AES_CTR;
|
||||
} else if (jmode == gCryptoModes.AesCbc) {
|
||||
mode = CryptoPlugin::kMode_AES_CBC;
|
||||
} else {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID);
|
||||
|
||||
CryptoPlugin::Pattern pattern;
|
||||
if (patternObj != NULL) {
|
||||
pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID);
|
||||
pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID);
|
||||
}
|
||||
|
||||
status_t err = OK;
|
||||
|
||||
@@ -1360,7 +1390,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
|
||||
index, offset,
|
||||
subSamples, numSubSamples,
|
||||
(const uint8_t *)key, (const uint8_t *)iv,
|
||||
(CryptoPlugin::Mode)mode,
|
||||
mode,
|
||||
pattern,
|
||||
timestampUs,
|
||||
flags,
|
||||
&errorDetailMsg);
|
||||
@@ -1658,6 +1689,22 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
|
||||
|
||||
CHECK(gFields.postEventFromNativeID != NULL);
|
||||
|
||||
jfieldID field;
|
||||
field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I");
|
||||
CHECK(field != NULL);
|
||||
gCryptoModes.Unencrypted =
|
||||
env->GetStaticIntField(clazz.get(), field);
|
||||
|
||||
field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CTR", "I");
|
||||
CHECK(field != NULL);
|
||||
gCryptoModes.AesCtr =
|
||||
env->GetStaticIntField(clazz.get(), field);
|
||||
|
||||
field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CBC", "I");
|
||||
CHECK(field != NULL);
|
||||
gCryptoModes.AesCbc =
|
||||
env->GetStaticIntField(clazz.get(), field);
|
||||
|
||||
clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
|
||||
CHECK(clazz.get() != NULL);
|
||||
|
||||
@@ -1682,10 +1729,22 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
|
||||
gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
|
||||
CHECK(gFields.cryptoInfoModeID != NULL);
|
||||
|
||||
gFields.cryptoInfoPatternID = env->GetFieldID(clazz.get(), "pattern",
|
||||
"Landroid/media/MediaCodec$CryptoInfo$Pattern;");
|
||||
CHECK(gFields.cryptoInfoPatternID != NULL);
|
||||
|
||||
clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo$Pattern"));
|
||||
CHECK(clazz.get() != NULL);
|
||||
|
||||
gFields.patternEncryptBlocksID = env->GetFieldID(clazz.get(), "mEncryptBlocks", "I");
|
||||
CHECK(gFields.patternEncryptBlocksID != NULL);
|
||||
|
||||
gFields.patternSkipBlocksID = env->GetFieldID(clazz.get(), "mSkipBlocks", "I");
|
||||
CHECK(gFields.patternSkipBlocksID != NULL);
|
||||
|
||||
clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
|
||||
CHECK(clazz.get() != NULL);
|
||||
|
||||
jfieldID field;
|
||||
field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
|
||||
CHECK(field != NULL);
|
||||
gCryptoErrorCodes.cryptoErrorNoKey =
|
||||
|
||||
@@ -81,6 +81,7 @@ struct JMediaCodec : public AHandler {
|
||||
const uint8_t key[16],
|
||||
const uint8_t iv[16],
|
||||
CryptoPlugin::Mode mode,
|
||||
const CryptoPlugin::Pattern &pattern,
|
||||
int64_t presentationTimeUs,
|
||||
uint32_t flags,
|
||||
AString *errorDetailMsg);
|
||||
|
||||
Reference in New Issue
Block a user