Support multiple codecs per crypto instance
    
The initial drm hidl hal implementation assumed one
codec per crypto instance, but in fact there can be
multiple codecs per crypto instance. This change
extends the drm hal to allow multiple memory heaps
per crypto plugin. It fixes the issue of mapping
memory frequently during playback.

bug:35275191

Test: manual verification with Play Movies on angler
and in binderized mode on marlin

Change-Id: I0ec36856248623d2ad8acb8ce9873e9274883a40
diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp
index fb61ede..4a4171b 100644
--- a/drm/1.0/default/CryptoPlugin.cpp
+++ b/drm/1.0/default/CryptoPlugin.cpp
@@ -49,8 +49,9 @@
         return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
     }
 
-    Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base) {
-        mSharedBufferBase = mapMemory(base);
+    Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
+            uint32_t bufferId) {
+        mSharedBufferMap[bufferId] = mapMemory(base);
         return Void();
     }
 
@@ -62,11 +63,19 @@
             const DestinationBuffer& destination,
             decrypt_cb _hidl_cb) {
 
-        if (mSharedBufferBase == NULL) {
-            _hidl_cb(Status::BAD_VALUE, 0, "decrypt buffer base not set");
+        if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
+            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set");
             return Void();
         }
 
+        if (destination.type == BufferType::SHARED_MEMORY) {
+            const SharedBuffer& dest = destination.nonsecureMemory;
+            if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
+                _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set");
+                return Void();
+            }
+        }
+
         android::CryptoPlugin::Mode legacyMode;
         switch(mode) {
         case Mode::UNENCRYPTED:
@@ -97,20 +106,22 @@
         }
 
         AString detailMessage;
+        sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
 
-        if (source.offset + offset + source.size > mSharedBufferBase->getSize()) {
+        if (source.offset + offset + source.size > sourceBase->getSize()) {
             _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
             return Void();
         }
 
         uint8_t *base = static_cast<uint8_t *>
-                (static_cast<void *>(mSharedBufferBase->getPointer()));
+                (static_cast<void *>(sourceBase->getPointer()));
         void *srcPtr = static_cast<void *>(base + source.offset + offset);
 
         void *destPtr = NULL;
         if (destination.type == BufferType::SHARED_MEMORY) {
             const SharedBuffer& destBuffer = destination.nonsecureMemory;
-            if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) {
+            sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
+            if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
                 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
                 return Void();
             }
diff --git a/drm/1.0/default/CryptoPlugin.h b/drm/1.0/default/CryptoPlugin.h
index f805f09..11cc2aa 100644
--- a/drm/1.0/default/CryptoPlugin.h
+++ b/drm/1.0/default/CryptoPlugin.h
@@ -57,8 +57,8 @@
     Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
             override;
 
-    Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base)
-            override;
+    Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base,
+        uint32_t bufferId) 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,
@@ -68,7 +68,7 @@
 
 private:
     android::CryptoPlugin *mLegacyPlugin;
-    sp<IMemory> mSharedBufferBase;
+    std::map<uint32_t, sp<IMemory> > mSharedBufferMap;
 
     CryptoPlugin() = delete;
     CryptoPlugin(const CryptoPlugin &) = delete;