From 631a80d493ad977b1bcc2fc64d82d136fd4f9ae4 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Sun, 14 Feb 2021 02:23:55 -0800 Subject: [PATCH] MediaCodec: comprehensive CryptoException messages Bug: 162255728 Test: MediaDrmTest#testExceptionMessage Change-Id: I05f6217304a01a4d49694c95baa91c3835327e8d --- media/jni/android_media_MediaCodec.cpp | 26 +++++++++++++++++++------- media/jni/android_media_MediaCodec.h | 4 ++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 71c86cc7d42d5..1870a939f0dc6 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -312,6 +313,7 @@ status_t JMediaCodec::configure( mGraphicOutput = (mime.startsWithIgnoreCase("video/") || mime.startsWithIgnoreCase("image/")) && !(flags & CONFIGURE_FLAG_ENCODE); mHasCryptoOrDescrambler = (crypto != nullptr) || (descrambler != nullptr); + mCrypto = crypto; return mCodec->configure( format, mSurfaceTextureClient, crypto, descrambler, flags); @@ -1103,6 +1105,8 @@ void JMediaCodec::onMessageReceived(const sp &msg) { } } +jint MediaErrorToJavaError(status_t err); + } // namespace android //////////////////////////////////////////////////////////////////////////////// @@ -1150,7 +1154,8 @@ static void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, c env->Throw(exception); } -static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { +static void throwCryptoException(JNIEnv *env, status_t err, const char *msg, + const sp &crypto) { ScopedLocalRef clazz( env, env->FindClass("android/media/MediaCodec$CryptoException")); CHECK(clazz.get() != NULL); @@ -1159,7 +1164,7 @@ static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { env->GetMethodID(clazz.get(), "", "(ILjava/lang/String;)V"); CHECK(constructID != NULL); - const char *defaultMsg = "Unknown Error"; + std::string defaultMsg = "Unknown Error"; /* translate OS errors to Java API CryptoException errorCodes (which are positive) */ switch (err) { @@ -1199,11 +1204,17 @@ static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { err = gCryptoErrorCodes.cryptoErrorLostState; defaultMsg = "Session state was lost, open a new session and retry"; break; - default: /* Other negative DRM error codes go out as is. */ + default: /* Other negative DRM error codes go out best-effort. */ + err = MediaErrorToJavaError(err); + defaultMsg = StrCryptoError(err); break; } - jstring msgObj = env->NewStringUTF(msg != NULL ? msg : defaultMsg); + std::string msgStr(msg != NULL ? msg : defaultMsg.c_str()); + if (crypto != NULL) { + msgStr = DrmUtils::GetExceptionMessage(err, msgStr.c_str(), crypto); + } + jstring msgObj = env->NewStringUTF(msgStr.c_str()); jthrowable exception = (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); @@ -1213,7 +1224,7 @@ static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { static jint throwExceptionAsNecessary( JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL, - const char *msg = NULL) { + const char *msg = NULL, const sp& crypto = NULL) { switch (err) { case OK: return 0; @@ -1237,7 +1248,7 @@ static jint throwExceptionAsNecessary( default: if (isCryptoError(err)) { - throwCryptoException(env, err, msg); + throwCryptoException(env, err, msg, crypto); return 0; } throwCodecException(env, err, actionCode, msg); @@ -1899,7 +1910,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer( subSamples = NULL; throwExceptionAsNecessary( - env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); + env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str(), + codec->getCrypto()); } static jobject android_media_MediaCodec_mapHardwareBuffer(JNIEnv *env, jclass, jobject bufferObj) { diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index a58f9a74b5635..f16bcf3c88e47 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -164,6 +164,8 @@ struct JMediaCodec : public AHandler { bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; } + const sp &getCrypto() { return mCrypto; } + protected: virtual ~JMediaCodec(); @@ -193,6 +195,8 @@ private: status_t mInitStatus; + sp mCrypto; + template status_t createByteBufferFromABuffer( JNIEnv *env, bool readOnly, bool clearBuffer, const sp &buffer,