Update shared memory access method in the crypto plugin hal

Required for functionality and performance

Test: gtests passing

bug:32815560
bug:34234561
Change-Id: I712bc4c332ff5721cf1369357d456b364d84967d
diff --git a/drm/crypto/1.0/ICryptoPlugin.hal b/drm/crypto/1.0/ICryptoPlugin.hal
index 52c1d02..26f0ffd 100644
--- a/drm/crypto/1.0/ICryptoPlugin.hal
+++ b/drm/crypto/1.0/ICryptoPlugin.hal
@@ -57,6 +57,15 @@
     setMediaDrmSession(vec<uint8_t> sessionId) generates(Status status);
 
     /**
+     * Set a shared memory base for subsequent decrypt operations. The buffer
+     * base is a hidl_memory which maps shared memory in the HAL module.
+     * After the shared buffer base is established, the decrypt() method
+     * receives SharedBuffer instances which specify the buffer address range
+     * for decrypt source and destination addresses.
+     */
+    setSharedBufferBase(memory base);
+
+    /**
      * Decrypt an array of subsamples from the source memory buffer to the
      * destination memory buffer.
      *
@@ -91,6 +100,6 @@
      */
     decrypt(bool secure, uint8_t[16] keyId, uint8_t[16] iv, Mode mode,
         Pattern pattern, vec<SubSample> subSamples,
-            memory source, uint32_t offset, DestinationBuffer destination)
+            SharedBuffer source, uint64_t offset, DestinationBuffer destination)
         generates(Status status, uint32_t bytesWritten, string detailedError);
 };
diff --git a/drm/crypto/1.0/default/CryptoPlugin.cpp b/drm/crypto/1.0/default/CryptoPlugin.cpp
index 81365c8..2e41cb3 100644
--- a/drm/crypto/1.0/default/CryptoPlugin.cpp
+++ b/drm/crypto/1.0/default/CryptoPlugin.cpp
@@ -17,15 +17,14 @@
 #include "CryptoPlugin.h"
 #include "TypeConvert.h"
 
-#include <media/stagefright/foundation/AString.h>
-
-#include <hidlmemory/mapping.h>
 #include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include <media/stagefright/foundation/AString.h>
 #include <utils/Log.h>
 
+using android::hardware::hidl_memory;
 using android::hidl::memory::V1_0::IMemory;
 
-
 namespace android {
 namespace hardware {
 namespace drm {
@@ -50,11 +49,16 @@
         return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
     }
 
+    Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base) {
+        mSharedBufferBase = mapMemory(base);
+        return Void();
+    }
+
     Return<void> CryptoPlugin::decrypt(bool secure,
             const hidl_array<uint8_t, 16>& keyId,
             const hidl_array<uint8_t, 16>& iv, Mode mode,
             const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
-            const hidl_memory& source, uint32_t offset,
+            const SharedBuffer& source, uint32_t offset,
             const DestinationBuffer& destination,
             decrypt_cb _hidl_cb) {
 
@@ -89,19 +93,23 @@
 
         AString detailMessage;
 
-        sp<IMemory> sharedSourceMemory = mapMemory(source);
+        if (source.offset + offset + source.size > mSharedBufferBase->getSize()) {
+            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+            return Void();
+        }
 
-        void *srcPtr = static_cast<void *>(sharedSourceMemory->getPointer());
-        uint8_t *offsetSrc = static_cast<uint8_t *>(srcPtr) + offset;
-        srcPtr = static_cast<void *>(offsetSrc);
+        uint8_t *base = static_cast<uint8_t *>
+                (static_cast<void *>(mSharedBufferBase->getPointer()));
+        void *srcPtr = static_cast<void *>(base + source.offset + offset);
 
-        sp<IMemory> sharedDestinationMemory;
         void *destPtr = NULL;
-
         if (destination.type == BufferType::SHARED_MEMORY) {
-            sharedDestinationMemory = mapMemory(destination.nonsecureMemory);
-            sharedDestinationMemory->update();
-            destPtr = sharedDestinationMemory->getPointer();
+            const SharedBuffer& destBuffer = destination.nonsecureMemory;
+            if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) {
+                _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+                return Void();
+            }
+            destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
         } else if (destination.type == BufferType::NATIVE_HANDLE) {
             native_handle_t *handle = const_cast<native_handle_t *>(
                     destination.secureMemory.getNativeHandle());
@@ -111,10 +119,6 @@
                 legacyMode, legacyPattern, srcPtr, legacySubSamples,
                 subSamples.size(), destPtr, &detailMessage);
 
-        if (destination.type == BufferType::SHARED_MEMORY) {
-            sharedDestinationMemory->commit();
-        }
-
         delete[] legacySubSamples;
 
         uint32_t status;
diff --git a/drm/crypto/1.0/default/CryptoPlugin.h b/drm/crypto/1.0/default/CryptoPlugin.h
index b1473f1..c367d0b 100644
--- a/drm/crypto/1.0/default/CryptoPlugin.h
+++ b/drm/crypto/1.0/default/CryptoPlugin.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
 
 #include <media/hardware/CryptoAPI.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 #include <android/hardware/drm/crypto/1.0/ICryptoPlugin.h>
 #include <hidl/Status.h>
 
@@ -38,6 +39,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hidl::memory::V1_0::IMemory;
 using ::android::sp;
 
 struct CryptoPlugin : public ICryptoPlugin {
@@ -56,14 +58,18 @@
     Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
             override;
 
+    Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base)
+            override;
+
     Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
             const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
-            const hidl_vec<SubSample>& subSamples, const hidl_memory& source,
+            const hidl_vec<SubSample>& subSamples, const SharedBuffer& source,
             uint32_t offset, const DestinationBuffer& destination,
             decrypt_cb _hidl_cb) override;
 
 private:
     android::CryptoPlugin *mLegacyPlugin;
+    sp<IMemory> mSharedBufferBase;
 
     CryptoPlugin() = delete;
     CryptoPlugin(const CryptoPlugin &) = delete;
diff --git a/drm/crypto/1.0/types.hal b/drm/crypto/1.0/types.hal
index e71d73a..1ba2776 100644
--- a/drm/crypto/1.0/types.hal
+++ b/drm/crypto/1.0/types.hal
@@ -114,6 +114,23 @@
     NATIVE_HANDLE = 1,
 };
 
+/**
+ * A SharedBuffer describes a decrypt buffer which is defined by an offset and
+ * a size.  The offset is relative to the shared memory base which is established
+ * using setSharedMemoryBase().
+ */
+struct SharedBuffer {
+    /**
+     * The offset from the shared memory base
+     */
+    uint64_t offset;
+
+    /**
+     * The size of the shared buffer in bytes
+     */
+    uint64_t size;
+};
+
 
 /**
  * A decrypt destination buffer can be either normal user-space shared
@@ -131,7 +148,7 @@
      * If type == SHARED_MEMORY, the decrypted data must be written
      * to user-space non-secure shared memory.
      */
-    memory nonsecureMemory;
+    SharedBuffer nonsecureMemory;
 
     /**
      * If type == NATIVE_HANDLE, the decrypted data must be written