Allow propagation of error information and description from the CryptoPlugin to

the higher layers.

Change-Id: I9f434ad55cdf575803c208bedf47b607baff2330
related-to-bug: 6365261
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index ebb5d58..5a43829 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -28,6 +28,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/DataSource.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/MediaCodecList.h>
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index 376c326..32a2cf7 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -24,6 +24,8 @@
 
 namespace android {
 
+struct AString;
+
 struct ICrypto : public IInterface {
     DECLARE_META_INTERFACE(Crypto);
 
@@ -46,7 +48,8 @@
             CryptoPlugin::Mode mode,
             const void *srcPtr,
             const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-            void *dstPtr) = 0;
+            void *dstPtr,
+            AString *errorDetailMsg) = 0;
 
 private:
     DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 107699e..d09049e 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -28,6 +28,7 @@
 struct ABuffer;
 struct ACodec;
 struct AMessage;
+struct AString;
 struct ICrypto;
 struct SoftwareRenderer;
 struct SurfaceTextureClient;
@@ -72,7 +73,8 @@
             size_t offset,
             size_t size,
             int64_t presentationTimeUs,
-            uint32_t flags);
+            uint32_t flags,
+            AString *errorDetailMsg = NULL);
 
     status_t queueSecureInputBuffer(
             size_t index,
@@ -83,7 +85,8 @@
             const uint8_t iv[16],
             CryptoPlugin::Mode mode,
             int64_t presentationTimeUs,
-            uint32_t flags);
+            uint32_t flags,
+            AString *errorDetailMsg = NULL);
 
     status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
 
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index 8889520..bb01467 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -55,8 +55,12 @@
     ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
     ERROR_DRM_TAMPER_DETECTED               = DRM_ERROR_BASE - 7,
 
-    ERROR_DRM_WV_VENDOR_MAX                 = DRM_ERROR_BASE - 500,
-    ERROR_DRM_WV_VENDOR_MIN                 = DRM_ERROR_BASE - 999,
+    ERROR_DRM_VENDOR_MAX                    = DRM_ERROR_BASE - 500,
+    ERROR_DRM_VENDOR_MIN                    = DRM_ERROR_BASE - 999,
+
+    // Deprecated
+    ERROR_DRM_WV_VENDOR_MAX                 = ERROR_DRM_VENDOR_MAX,
+    ERROR_DRM_WV_VENDOR_MIN                 = ERROR_DRM_VENDOR_MIN,
 
     // Heartbeat Error Codes
     HEARTBEAT_ERROR_BASE = -3000,
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index d51fe01..3452e5c 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -20,7 +20,9 @@
 
 #include <binder/Parcel.h>
 #include <media/ICrypto.h>
+#include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
 
 namespace android {
 
@@ -96,7 +98,8 @@
             CryptoPlugin::Mode mode,
             const void *srcPtr,
             const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-            void *dstPtr) {
+            void *dstPtr,
+            AString *errorDetailMsg) {
         Parcel data, reply;
         data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
         data.writeInt32(secure);
@@ -135,6 +138,10 @@
 
         status_t result = reply.readInt32();
 
+        if (result >= ERROR_DRM_VENDOR_MIN && result <= ERROR_DRM_VENDOR_MAX) {
+            errorDetailMsg->setTo(reply.readCString());
+        }
+
         if (result != OK) {
             return result;
         }
@@ -251,6 +258,8 @@
                 dstPtr = malloc(totalSize);
             }
 
+            AString errorDetailMsg;
+
             status_t err = decrypt(
                     secure,
                     key,
@@ -258,10 +267,16 @@
                     mode,
                     srcData,
                     subSamples, numSubSamples,
-                    dstPtr);
+                    dstPtr,
+                    &errorDetailMsg);
 
             reply->writeInt32(err);
 
+            if (err >= ERROR_DRM_VENDOR_MIN
+                    && err <= ERROR_DRM_VENDOR_MAX) {
+                reply->writeCString(errorDetailMsg.c_str());
+            }
+
             if (!secure) {
                 if (err == OK) {
                     reply->write(dstPtr, totalSize);
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index 574ae71..d35d5b1 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -22,6 +22,7 @@
 
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaErrors.h>
 
@@ -147,7 +148,8 @@
         CryptoPlugin::Mode mode,
         const void *srcPtr,
         const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-        void *dstPtr) {
+        void *dstPtr,
+        AString *errorDetailMsg) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
@@ -159,7 +161,8 @@
     }
 
     return mPlugin->decrypt(
-            secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr);
+            secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr,
+            errorDetailMsg);
 }
 
 }  // namespace android
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 74de2b5..c5aa3c6 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -49,7 +49,8 @@
             CryptoPlugin::Mode mode,
             const void *srcPtr,
             const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-            void *dstPtr);
+            void *dstPtr,
+            AString *errorDetailMsg);
 
 private:
     mutable Mutex mLock;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a382f1c..2df0dd2 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -27,6 +27,7 @@
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/ACodec.h>
 #include <media/stagefright/MediaErrors.h>
@@ -179,13 +180,19 @@
         size_t offset,
         size_t size,
         int64_t presentationTimeUs,
-        uint32_t flags) {
+        uint32_t flags,
+        AString *errorDetailMsg) {
+    if (errorDetailMsg != NULL) {
+        errorDetailMsg->clear();
+    }
+
     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
     msg->setSize("index", index);
     msg->setSize("offset", offset);
     msg->setSize("size", size);
     msg->setInt64("timeUs", presentationTimeUs);
     msg->setInt32("flags", flags);
+    msg->setPointer("errorDetailMsg", errorDetailMsg);
 
     sp<AMessage> response;
     return PostAndAwaitResponse(msg, &response);
@@ -200,7 +207,12 @@
         const uint8_t iv[16],
         CryptoPlugin::Mode mode,
         int64_t presentationTimeUs,
-        uint32_t flags) {
+        uint32_t flags,
+        AString *errorDetailMsg) {
+    if (errorDetailMsg != NULL) {
+        errorDetailMsg->clear();
+    }
+
     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
     msg->setSize("index", index);
     msg->setSize("offset", offset);
@@ -211,9 +223,12 @@
     msg->setInt32("mode", mode);
     msg->setInt64("timeUs", presentationTimeUs);
     msg->setInt32("flags", flags);
+    msg->setPointer("errorDetailMsg", errorDetailMsg);
 
     sp<AMessage> response;
-    return PostAndAwaitResponse(msg, &response);
+    status_t err = PostAndAwaitResponse(msg, &response);
+
+    return err;
 }
 
 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
@@ -1234,9 +1249,6 @@
     }
 
     sp<AMessage> reply = info->mNotify;
-    info->mNotify = NULL;
-    info->mOwnedByClient = false;
-
     info->mData->setRange(offset, size);
     info->mData->meta()->setInt64("timeUs", timeUs);
 
@@ -1253,6 +1265,9 @@
             return -ERANGE;
         }
 
+        AString *errorDetailMsg;
+        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
+
         status_t err = mCrypto->decrypt(
                 (mFlags & kFlagIsSecure) != 0,
                 key,
@@ -1261,7 +1276,8 @@
                 info->mEncryptedData->base() + offset,
                 subSamples,
                 numSubSamples,
-                info->mData->base());
+                info->mData->base(),
+                errorDetailMsg);
 
         if (err != OK) {
             return err;
@@ -1273,6 +1289,9 @@
     reply->setBuffer("buffer", info->mData);
     reply->post();
 
+    info->mNotify = NULL;
+    info->mOwnedByClient = false;
+
     return OK;
 }