Support vec<memory> in HIDL.

Test: hidl interfaces compile with vec<memory>
Test: hidl_test

Bug: 36727951
Bug: 63899698

Merged-In: I68092eda26a6ead11bd09ea6c9bb64655207cb5f
Change-Id: I68092eda26a6ead11bd09ea6c9bb64655207cb5f
diff --git a/MemoryType.cpp b/MemoryType.cpp
index 2585d4a..251691e 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -141,6 +141,10 @@
     return true;
 }
 
+bool MemoryType::isMemory() const {
+    return true;
+}
+
 bool MemoryType::isJavaCompatible() const {
     return false;
 }
diff --git a/MemoryType.h b/MemoryType.h
index e813b35..cd7329a 100644
--- a/MemoryType.h
+++ b/MemoryType.h
@@ -57,6 +57,7 @@
     bool needsEmbeddedReadWrite() const override;
     bool resultNeedsDeref() const override;
 
+    bool isMemory() const override;
     bool isJavaCompatible() const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
diff --git a/Type.cpp b/Type.cpp
index b2efc20..cc31a26 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -78,6 +78,10 @@
     return false;
 }
 
+bool Type::isMemory() const {
+    return false;
+}
+
 bool Type::isCompoundType() const {
     return false;
 }
diff --git a/Type.h b/Type.h
index 26eeab0..1e30850 100644
--- a/Type.h
+++ b/Type.h
@@ -43,6 +43,7 @@
     virtual bool isHandle() const;
     virtual bool isInterface() const;
     virtual bool isNamedType() const;
+    virtual bool isMemory() const;
     virtual bool isPointer() const;
     virtual bool isScope() const;
     virtual bool isScalar() const;
diff --git a/VectorType.cpp b/VectorType.cpp
index 22c997f..4d1dae8 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -55,6 +55,9 @@
     if (elementType->isHandle()) {
         return true;
     }
+    if (elementType->isMemory()) {
+        return true;
+    }
     if (elementType->isTemplatedType()) {
         Type *inner = static_cast<TemplatedType *>(elementType)->getElementType();
         return this->isCompatibleElementType(inner) && !inner->isInterface();
diff --git a/test/hidl_test_client.cpp b/test/hidl_test_client.cpp
index 1fbf874..27dc532 100644
--- a/test/hidl_test_client.cpp
+++ b/test/hidl_test_client.cpp
@@ -784,6 +784,66 @@
     memory->commit();
 }
 
+TEST_F(HidlTest, BatchSharedMemory) {
+    const uint8_t kValue = 0xCA;
+    const uint64_t kBatchSize = 2;
+    hidl_vec<hidl_memory> batchCopy;
+
+    EXPECT_OK(ashmemAllocator->batchAllocate(1024, kBatchSize,
+        [&](bool success, const hidl_vec<hidl_memory>& batch) {
+            ASSERT_TRUE(success);
+            EXPECT_EQ(kBatchSize, batch.size());
+
+            for (uint64_t i = 0; i < batch.size(); i++) {
+                sp<IMemory> memory = mapMemory(batch[i]);
+
+                EXPECT_NE(nullptr, memory.get());
+
+                uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(memory->getPointer()));
+                EXPECT_NE(nullptr, data);
+
+                EXPECT_EQ(memory->getSize(), batch[i].size());
+
+                memory->update();
+                memset(data, kValue, memory->getSize());
+                memory->commit();
+            }
+
+            batchCopy = batch;
+        }));
+
+    for (uint64_t i = 0; i < batchCopy.size(); i++) {
+        // Test the memory persists after the call
+        sp<IMemory> memory = mapMemory(batchCopy[i]);
+
+        EXPECT_NE(memory, nullptr);
+
+        uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(memory->getPointer()));
+        EXPECT_NE(data, nullptr);
+
+        memory->read();
+        for (size_t i = 0; i < batchCopy[i].size(); i++) {
+            EXPECT_EQ(kValue, data[i]);
+        }
+        memory->commit();
+    }
+}
+
+inline uint64_t operator""_GB(unsigned long long num) {
+    return num * 1024 * 1024 * 1024;
+}
+
+TEST_F(HidlTest, FailedBatchSharedMemory) {
+    EXPECT_OK(ashmemAllocator->batchAllocate(1024, UINT64_MAX, [&](bool success, const auto& v) {
+        EXPECT_FALSE(success);
+        EXPECT_EQ(0u, v.size());
+    }));
+    EXPECT_OK(ashmemAllocator->batchAllocate(1_GB, 1024, [&](bool success, const auto& v) {
+        EXPECT_FALSE(success);
+        EXPECT_EQ(0u, v.size());
+    }));
+}
+
 TEST_F(HidlTest, NullSharedMemory) {
     hidl_memory memory{};