Generate correct Parcel verification code.

Make sure we pass in correct sizes into readBuffer()
and readEmbeddedBuffer() calls.

Same thing for HwBlob.readBuffer() and
HwBlob.readEmbeddedBuffer().

Bug: 30498700
Test: hidl_test, hidl_test_java, Youtube, Maps, Netflix, Camera

Change-Id: Ied2d9dc46538da3fcf5b1acbf1e7558e0743d3a2
Merged-In: Ied2d9dc46538da3fcf5b1acbf1e7558e0743d3a2
diff --git a/VectorType.cpp b/VectorType.cpp
index 237113e..9bdd91e 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -156,7 +156,10 @@
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
@@ -485,6 +488,8 @@
     }
 
     if (mElementType->isArray()) {
+        size_t align, size;
+        getAlignmentAndSize(&align, &size);
         if (isReader) {
             out << " new "
                 << getJavaType(false /* forInitializer */)
@@ -498,10 +503,10 @@
 
         if (isReader) {
             out << parcelObj
-                << ".readBuffer();\n";
+                << ".readBuffer("
+                << size
+                << " /* size */);\n";
         } else {
-            size_t align, size;
-            getAlignmentAndSize(&align, &size);
 
             out << "new android.os.HwBlob("
                 << size
@@ -578,10 +583,19 @@
         const std::string &fieldName,
         const std::string &offset,
         bool isReader) {
+    size_t elementAlign, elementSize;
+    elementType->getAlignmentAndSize(&elementAlign, &elementSize);
+
     if (isReader) {
         out << "{\n";
         out.indent();
 
+        out << "int _hidl_vec_size = "
+            << blobName
+            << ".getInt32("
+            << offset
+            << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
+
         out << "android.os.HwBlob childBlob = "
             << parcelName
             << ".readEmbeddedBuffer(\n";
@@ -589,7 +603,9 @@
         out.indent();
         out.indent();
 
-        out << blobName
+        out << "_hidl_vec_size * "
+            << elementSize << ","
+            << blobName
             << ".handle(),\n"
             << offset
             << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
@@ -599,12 +615,6 @@
         out.unindent();
 
         out << fieldName << ".clear();\n";
-        out << "int _hidl_vec_size = "
-            << blobName
-            << ".getInt32("
-            << offset
-            << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
-
         std::string iteratorName = "_hidl_index_" + std::to_string(depth);
 
         out << "for (int "
@@ -620,9 +630,6 @@
 
         elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
 
-        size_t elementAlign, elementSize;
-        elementType->getAlignmentAndSize(&elementAlign, &elementSize);
-
         elementType->emitJavaFieldReaderWriter(
                 out,
                 depth + 1,
@@ -662,9 +669,6 @@
         << offset
         << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
 
-    size_t elementAlign, elementSize;
-    elementType->getAlignmentAndSize(&elementAlign, &elementSize);
-
     // XXX make HwBlob constructor take a long instead of an int?
     out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
         << elementSize
@@ -743,10 +747,16 @@
 
 // All hidl_vec<T> have the same size.
 static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
-void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
+
+// static
+void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
     *align = 8;  // hidl_vec<T>
     *size = assertion.size();
 }
 
+void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
+    VectorType::getAlignmentAndSizeStatic(align, size);
+}
+
 }  // namespace android