stagefright: ICrypto: enable passing secure buffers in native_handle

Previously secure buffers were passed as opaque
void * values, which no longer works since
mediadrmserver is now a separate process from
mediaserver.

Bug: 22990512
Change-Id: I5c458ba19e78e20d1bd5a5899df0bce16f71bfd8
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 79059c6..26dd2c9 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -95,7 +95,7 @@
     }
 
     virtual ssize_t decrypt(
-            bool secure,
+            DestinationType dstType,
             const uint8_t key[16],
             const uint8_t iv[16],
             CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
@@ -105,7 +105,7 @@
             AString *errorDetailMsg) {
         Parcel data, reply;
         data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
-        data.writeInt32(secure);
+        data.writeInt32((int32_t)dstType);
         data.writeInt32(mode);
         data.writeInt32(pattern.mEncryptBlocks);
         data.writeInt32(pattern.mSkipBlocks);
@@ -136,8 +136,12 @@
         data.writeInt32(numSubSamples);
         data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
-        if (secure) {
+        if (dstType == kDestinationTypeNativeHandle) {
+            data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
+        } else if (dstType == kDestinationTypeOpaqueHandle) {
             data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
+        } else {
+            dstType = kDestinationTypeVmPointer;
         }
 
         remote()->transact(DECRYPT, data, &reply);
@@ -148,7 +152,7 @@
             errorDetailMsg->setTo(reply.readCString());
         }
 
-        if (!secure && result >= 0) {
+        if (dstType == kDestinationTypeVmPointer && result >= 0) {
             reply.read(dstPtr, result);
         }
 
@@ -276,7 +280,7 @@
         {
             CHECK_INTERFACE(ICrypto, data, reply);
 
-            bool secure = data.readInt32() != 0;
+            DestinationType dstType = (DestinationType)data.readInt32();
             CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
             CryptoPlugin::Pattern pattern;
             pattern.mEncryptBlocks = data.readInt32();
@@ -306,10 +310,16 @@
                     subSamples,
                     sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
-            void *secureBufferId, *dstPtr;
-            if (secure) {
+            native_handle_t *nativeHandle = NULL;
+            void *secureBufferId = NULL, *dstPtr;
+            if (dstType == kDestinationTypeNativeHandle) {
+                nativeHandle = data.readNativeHandle();
+                dstPtr = static_cast<void *>(nativeHandle);
+            } else if (dstType == kDestinationTypeOpaqueHandle) {
                 secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
+                dstPtr = secureBufferId;
             } else {
+                dstType = kDestinationTypeVmPointer;
                 dstPtr = malloc(totalSize);
             }
 
@@ -340,13 +350,13 @@
                 result = -EINVAL;
             } else {
                 result = decrypt(
-                    secure,
+                    dstType,
                     key,
                     iv,
                     mode, pattern,
                     sharedBuffer, offset,
                     subSamples, numSubSamples,
-                    secure ? secureBufferId : dstPtr,
+                    dstPtr,
                     &errorDetailMsg);
             }
 
@@ -356,13 +366,21 @@
                 reply->writeCString(errorDetailMsg.c_str());
             }
 
-            if (!secure) {
+            if (dstType == kDestinationTypeVmPointer) {
                 if (result >= 0) {
                     CHECK_LE(result, static_cast<ssize_t>(totalSize));
                     reply->write(dstPtr, result);
                 }
                 free(dstPtr);
                 dstPtr = NULL;
+            } else if (dstType == kDestinationTypeNativeHandle) {
+                int err;
+                if ((err = native_handle_close(nativeHandle)) < 0) {
+                    ALOGW("secure buffer native_handle_close failed: %d", err);
+                }
+                if ((err = native_handle_delete(nativeHandle)) < 0) {
+                    ALOGW("secure buffer native_handle_delete failed: %d", err);
+                }
             }
 
             delete[] subSamples;