DRM errors signaled by the CryptoPlugin are now visible to MediaCodec clients
through a custom exception "MediaCodec.CryptoException".
Change-Id: I30215e9e13bab68abad23e27dcead7c1accd07f1
related-to-bug: 6365261
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index a120a2f..8009fb5 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -36,6 +36,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/MediaErrors.h>
namespace android {
@@ -129,8 +130,10 @@
status_t JMediaCodec::queueInputBuffer(
size_t index,
- size_t offset, size_t size, int64_t timeUs, uint32_t flags) {
- return mCodec->queueInputBuffer(index, offset, size, timeUs, flags);
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags,
+ AString *errorDetailMsg) {
+ return mCodec->queueInputBuffer(
+ index, offset, size, timeUs, flags, errorDetailMsg);
}
status_t JMediaCodec::queueSecureInputBuffer(
@@ -142,10 +145,11 @@
const uint8_t iv[16],
CryptoPlugin::Mode mode,
int64_t presentationTimeUs,
- uint32_t flags) {
+ uint32_t flags,
+ AString *errorDetailMsg) {
return mCodec->queueSecureInputBuffer(
index, offset, subSamples, numSubSamples, key, iv, mode,
- presentationTimeUs, flags);
+ presentationTimeUs, flags, errorDetailMsg);
}
status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
@@ -251,7 +255,31 @@
setMediaCodec(env, thiz, NULL);
}
-static jint throwExceptionAsNecessary(JNIEnv *env, status_t err) {
+static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
+ jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException");
+ CHECK(clazz != NULL);
+
+ jmethodID constructID =
+ env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V");
+ CHECK(constructID != NULL);
+
+ jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
+
+ jthrowable exception =
+ (jthrowable)env->NewObject(clazz, constructID, err, msgObj);
+
+ env->Throw(exception);
+}
+
+static jint throwExceptionAsNecessary(
+ JNIEnv *env, status_t err, const char *msg = NULL) {
+ if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) {
+ // We'll throw our custom MediaCodec.CryptoException
+
+ throwCryptoException(env, err, msg);
+ return 0;
+ }
+
switch (err) {
case OK:
return 0;
@@ -383,10 +411,13 @@
return;
}
- status_t err = codec->queueInputBuffer(
- index, offset, size, timestampUs, flags);
+ AString errorDetailMsg;
- throwExceptionAsNecessary(env, err);
+ status_t err = codec->queueInputBuffer(
+ index, offset, size, timestampUs, flags, &errorDetailMsg);
+
+ throwExceptionAsNecessary(
+ env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}
static void android_media_MediaCodec_queueSecureInputBuffer(
@@ -497,13 +528,17 @@
}
}
+ AString errorDetailMsg;
+
if (err == OK) {
err = codec->queueSecureInputBuffer(
index, offset,
subSamples, numSubSamples,
(const uint8_t *)key, (const uint8_t *)iv,
(CryptoPlugin::Mode)mode,
- timestampUs, flags);
+ timestampUs,
+ flags,
+ &errorDetailMsg);
}
if (iv != NULL) {
@@ -519,7 +554,8 @@
delete[] subSamples;
subSamples = NULL;
- throwExceptionAsNecessary(env, err);
+ throwExceptionAsNecessary(
+ env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}
static jint android_media_MediaCodec_dequeueInputBuffer(
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 570c33b..e2688be 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -28,6 +28,7 @@
struct ALooper;
struct AMessage;
+struct AString;
struct ICrypto;
struct ISurfaceTexture;
struct MediaCodec;
@@ -52,7 +53,8 @@
status_t queueInputBuffer(
size_t index,
- size_t offset, size_t size, int64_t timeUs, uint32_t flags);
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags,
+ AString *errorDetailMsg);
status_t queueSecureInputBuffer(
size_t index,
@@ -63,7 +65,8 @@
const uint8_t iv[16],
CryptoPlugin::Mode mode,
int64_t presentationTimeUs,
- uint32_t flags);
+ uint32_t flags,
+ AString *errorDetailMsg);
status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs);