Merge "Add a method to associate MediaDrm session with MediaCrypto"
diff --git a/api/current.txt b/api/current.txt
index e2c6596..75a8df9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15323,6 +15323,7 @@
method public static final boolean isCryptoSchemeSupported(java.util.UUID);
method public final void release();
method public final boolean requiresSecureDecoderComponent(java.lang.String);
+ method public final void setMediaDrmSession(byte[]) throws android.media.MediaCryptoException;
}
public final class MediaCryptoException extends java.lang.Exception {
diff --git a/api/system-current.txt b/api/system-current.txt
index 22187da..d272c20 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16532,6 +16532,7 @@
method public static final boolean isCryptoSchemeSupported(java.util.UUID);
method public final void release();
method public final boolean requiresSecureDecoderComponent(java.lang.String);
+ method public final void setMediaDrmSession(byte[]) throws android.media.MediaCryptoException;
}
public final class MediaCryptoException extends java.lang.Exception {
diff --git a/media/java/android/media/MediaCrypto.java b/media/java/android/media/MediaCrypto.java
index c7c3fc2..da81b37 100644
--- a/media/java/android/media/MediaCrypto.java
+++ b/media/java/android/media/MediaCrypto.java
@@ -70,6 +70,20 @@
*/
public final native boolean requiresSecureDecoderComponent(String mime);
+ /**
+ * Associate a MediaDrm session with this MediaCrypto instance. The
+ * MediaDrm session is used to securely load decryption keys for a
+ * crypto scheme. The crypto keys loaded through the MediaDrm session
+ * may be selected for use during the decryption operation performed
+ * by {@link android.media.MediaCodec#queueSecureInputBuffer} by specifying
+ * their key ids in the {@link android.media.MediaCodec.CryptoInfo#key} field.
+ * @param sessionId the MediaDrm sessionId to associate with this
+ * MediaCrypto instance
+ * @throws MediaCryptoException on failure to set the sessionId
+ */
+ public final native void setMediaDrmSession(byte[] sessionId)
+ throws MediaCryptoException;
+
@Override
protected void finalize() {
native_finalize();
diff --git a/media/java/android/media/MediaCryptoException.java b/media/java/android/media/MediaCryptoException.java
index 44c5222..703e96f 100644
--- a/media/java/android/media/MediaCryptoException.java
+++ b/media/java/android/media/MediaCryptoException.java
@@ -17,8 +17,8 @@
package android.media;
/**
- * Exception thrown if MediaCrypto object could not be instantiated for
- * whatever reason.
+ * Exception thrown if MediaCrypto object could not be instantiated or
+ * if unable to perform an operation on the MediaCrypto object.
*/
public final class MediaCryptoException extends Exception {
public MediaCryptoException(String detailMessage) {
diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp
index d2216fb..a9accb02 100644
--- a/media/jni/android_media_MediaCrypto.cpp
+++ b/media/jni/android_media_MediaCrypto.cpp
@@ -140,6 +140,15 @@
return jcrypto->mCrypto;
}
+// JNI conversion utilities
+static Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) {
+ Vector<uint8_t> vector;
+ size_t length = env->GetArrayLength(byteArray);
+ vector.insertAt((size_t)0, length);
+ env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
+ return vector;
+}
+
} // namespace android
using namespace android;
@@ -274,6 +283,37 @@
return result ? JNI_TRUE : JNI_FALSE;
}
+static void android_media_MediaCrypto_setMediaDrmSession(
+ JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
+ if (jsessionId == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ sp<ICrypto> crypto = JCrypto::GetCrypto(env, thiz);
+
+ if (crypto == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
+
+ status_t err = crypto->setMediaDrmSession(sessionId);
+
+ String8 msg("setMediaDrmSession failed");
+ if (err == ERROR_DRM_SESSION_NOT_OPENED) {
+ msg += ": session not opened";
+ } else if (err == ERROR_UNSUPPORTED) {
+ msg += ": not supported by this crypto scheme";
+ } else if (err == NO_INIT) {
+ msg += ": crypto plugin not initialized";
+ } else if (err != OK) {
+ msg.appendFormat(": general failure (%d)", err);
+ }
+ jniThrowException(env, "android/media/MediaCryptoException", msg.string());
+}
+
static JNINativeMethod gMethods[] = {
{ "release", "()V", (void *)android_media_MediaCrypto_release },
{ "native_init", "()V", (void *)android_media_MediaCrypto_native_init },
@@ -289,6 +329,9 @@
{ "requiresSecureDecoderComponent", "(Ljava/lang/String;)Z",
(void *)android_media_MediaCrypto_requiresSecureDecoderComponent },
+
+ { "setMediaDrmSession", "([B)V",
+ (void *)android_media_MediaCrypto_setMediaDrmSession },
};
int register_android_media_Crypto(JNIEnv *env) {