Merge "Fix vts generation in hidl."
diff --git a/Annotation.cpp b/Annotation.cpp
index d3b4d01..1205079 100644
--- a/Annotation.cpp
+++ b/Annotation.cpp
@@ -16,6 +16,7 @@
 
 #include "Annotation.h"
 
+#include <android-base/logging.h>
 #include <hidl-util/Formatter.h>
 #include <vector>
 
@@ -43,6 +44,36 @@
     return mValues;
 }
 
+const std::string &AnnotationParam::getSingleValue() const {
+    CHECK_EQ(mValues->size(), 1u) << mName << " requires one values but has multiple";
+    return mValues->at(0);
+}
+
+std::string AnnotationParam::getSingleString() const {
+    std::string value = getSingleValue();
+
+    CHECK(value.size() >= 2 && value[0] == '"' && value[value.size() - 1] == '"')
+        << mName << " must be a string";
+
+    // unquote string
+    value = value.substr(1, value.size() - 2);
+
+    return value;
+}
+
+bool AnnotationParam::getSingleBool() const {
+    std::string value = getSingleString();
+
+    if (value == "true") {
+        return true;
+    } else if (value == "false") {
+        return false;
+    }
+
+    CHECK(false) << mName << " must be of boolean value (true/false).";
+    return false;
+}
+
 Annotation::Annotation(const char *name,AnnotationParamVector *params)
         : mName(name),
           mParams(params) {
diff --git a/Annotation.h b/Annotation.h
index 063b8e4..18d9ab0 100644
--- a/Annotation.h
+++ b/Annotation.h
@@ -37,6 +37,14 @@
     const std::string &getName() const;
     const std::vector<std::string> *getValues() const;
 
+    const std::string &getSingleValue() const;
+
+    /* Returns unquoted version of getSingleValue */
+    std::string getSingleString() const;
+
+    /* Returns value interpretted as a boolean */
+    bool getSingleBool() const;
+
 private:
     const std::string mName;
     std::vector<std::string> *mValues;
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 79d3e79..306cb9d 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -144,25 +144,16 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-
-        out << name
-            << " = ("
-            << getCppResultType()
-            << ")"
+        out << "_hidl_err = "
             << parcelObjDeref
             << "readBuffer(&"
             << parentName
-            << ");\n\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n\n";
 
-        out << "if (" << name << " == nullptr) {\n";
-
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         size_t numArrayElements = 1;
         for (auto size : mSizes) {
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 6527f86..64e588a 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -132,26 +132,17 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = (const "
-            << fullName()
-            << " *)"
+        out << "_hidl_err = "
             << parcelObjDeref
             << "readBuffer("
             << "&"
             << parentName
-            << ");\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n";
 
-        out << "if ("
-            << name
-            << " == nullptr) {\n";
-
-        out.indent([&]{
-            out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-            handleError2(out, mode);
-        });
-
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObjDeref
@@ -355,15 +346,71 @@
 
     Scope::emitTypeDeclarations(out);
 
-    for (const auto &field : *mFields) {
-        out << field->type().getCppStackType()
-            << " "
-            << field->name()
-            << ";\n";
+    if (!isJavaCompatible()) {
+        for (const auto &field : *mFields) {
+            out << field->type().getCppStackType()
+                << " "
+                << field->name()
+                << ";\n";
+        }
+
+        out.unindent();
+        out << "};\n\n";
+
+        return OK;
     }
 
-    out.unindent();
-    out << "};\n\n";
+    for (int pass = 0; pass < 2; ++pass) {
+        size_t offset = 0;
+        for (const auto &field : *mFields) {
+            size_t fieldAlign, fieldSize;
+            field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);
+
+            size_t pad = offset % fieldAlign;
+            if (pad > 0) {
+                offset += fieldAlign - pad;
+            }
+
+            if (pass == 0) {
+                out << field->type().getCppStackType()
+                    << " "
+                    << field->name()
+                    << " __attribute__ ((aligned("
+                    << fieldAlign
+                    << ")));\n";
+            } else {
+                out << "static_assert(offsetof("
+                    << fullName()
+                    << ", "
+                    << field->name()
+                    << ") == "
+                    << offset
+                    << ", \"wrong offset\");\n";
+            }
+
+            offset += fieldSize;
+        }
+
+        if (pass == 0) {
+            out.unindent();
+            out << "};\n\n";
+        }
+    }
+
+    size_t structAlign, structSize;
+    getAlignmentAndSize(&structAlign, &structSize);
+
+    out << "static_assert(sizeof("
+        << fullName()
+        << ") == "
+        << structSize
+        << ", \"wrong size\");\n";
+
+    out << "static_assert(__alignof("
+        << fullName()
+        << ") == "
+        << structAlign
+        << ", \"wrong alignment\");\n\n";
 
     return OK;
 }
@@ -973,6 +1020,11 @@
     }
 
     *size = offset;
+
+    if (*size == 0) {
+        // An empty struct still occupies a byte of space in C++.
+        *size = 1;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/EnumType.cpp b/EnumType.cpp
index 0f0542a..6ce8010 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -406,33 +406,37 @@
 
     const AnnotationParam *nameParam = annotation->getParam("name");
     if (nameParam != nullptr) {
-        CHECK_EQ(nameParam->getValues()->size(), 1u);
+        name = nameParam->getSingleString();
+    }
 
-        std::string quotedString = nameParam->getValues()->at(0);
-        name = quotedString.substr(1, quotedString.size() - 2);
+    bool exportParent = true;
+    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
+    if (exportParentParam != nullptr) {
+        exportParent = exportParentParam->getSingleBool();
     }
 
     std::string valuePrefix;
     const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
     if (prefixParam != nullptr) {
-        CHECK_EQ(prefixParam->getValues()->size(), 1u);
-
-        std::string quotedString = prefixParam->getValues()->at(0);
-        valuePrefix = quotedString.substr(1, quotedString.size() - 2);
+        valuePrefix = prefixParam->getSingleString();
     }
 
     std::string valueSuffix;
     const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
     if (suffixParam != nullptr) {
-        CHECK_EQ(suffixParam->getValues()->size(), 1u);
-
-        std::string quotedString = suffixParam->getValues()->at(0);
-        valueSuffix = quotedString.substr(1, quotedString.size() - 2);
+        valueSuffix = suffixParam->getSingleString();
     }
 
     const ScalarType *scalarType = mStorageType->resolveToScalarType();
     CHECK(scalarType != nullptr);
 
+    std::vector<const EnumType *> chain;
+    if (exportParent) {
+        getTypeChain(&chain);
+    } else {
+        chain = { this };
+    }
+
     if (forJava) {
         if (!name.empty()) {
             out << "public final class "
@@ -447,9 +451,6 @@
         const std::string typeName =
             scalarType->getJavaType(false /* forInitializer */);
 
-        std::vector<const EnumType *> chain;
-        getTypeChain(&chain);
-
         for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
             const auto &type = *it;
 
@@ -495,9 +496,6 @@
 
     out.indent();
 
-    std::vector<const EnumType *> chain;
-    getTypeChain(&chain);
-
     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
         const auto &type = *it;
 
diff --git a/FQName.cpp b/FQName.cpp
index 5e9e347..07eb219 100644
--- a/FQName.cpp
+++ b/FQName.cpp
@@ -298,11 +298,11 @@
 }
 
 std::string FQName::getInterfaceProxyName() const {
-    return "Bp" + getInterfaceBaseName();
+    return "BpHw" + getInterfaceBaseName();
 }
 
 std::string FQName::getInterfaceStubName() const {
-    return "Bn" + getInterfaceBaseName();
+    return "BnHw" + getInterfaceBaseName();
 }
 
 std::string FQName::getInterfacePassthroughName() const {
diff --git a/FmqType.cpp b/FmqType.cpp
index c22fd55..2f410f7 100644
--- a/FmqType.cpp
+++ b/FmqType.cpp
@@ -68,27 +68,16 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = (const "
-            << fullName()
-            << " *)"
+        out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer("
-            << "&"
+            << "readBuffer(&"
             << parentName
-            << ");\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n\n";
 
-        out << "if ("
-            << name
-            << " == nullptr) {\n";
-
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObjDeref
diff --git a/HandleType.cpp b/HandleType.cpp
index 72c3c46..6acecbc 100644
--- a/HandleType.cpp
+++ b/HandleType.cpp
@@ -64,22 +64,18 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = "
+        out << "const native_handle_t *"
+            << name << "_ptr;\n\n";
+
+        out << "_hidl_err = "
             << parcelObjDeref
-            << "readNativeHandleNoDup();\n\n";
+            << "readNativeHandleNoDup("
+            << "&" << name << "_ptr"
+            << ");\n\n";
 
-        out << "if ("
-            << name
-            << " == nullptr) {\n";
+        handleError(out, mode);
 
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        out << name << " = " << name << "_ptr;\n";
     } else {
         out << "_hidl_err = ";
         out << parcelObjDeref
@@ -111,8 +107,8 @@
         const std::string ptrName = "_hidl_" + sanitizedName  + "_ptr";
 
         out << "const native_handle_t *"
-            << ptrName
-            << " = "
+            << ptrName << ";\n"
+            << "_hidl_err = "
             << parcelObj
             << (parcelObjIsPointer ? "->" : ".")
             << "readEmbeddedNativeHandle(\n";
@@ -123,20 +119,15 @@
         out << parentName
             << ",\n"
             << offsetText
+            << ",\n"
+            << "&" << ptrName
+            << "\n"
             << ");\n\n";
 
         out.unindent();
         out.unindent();
 
-        out << "if ("
-            << ptrName
-            << " == nullptr) {\n";
-
-        out.indent();
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObj
diff --git a/Interface.cpp b/Interface.cpp
index 4c9e9a5..77681d4 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -50,6 +50,7 @@
     HIDL_SYSPROPS_CHANGED_TRANSACTION,
     HIDL_LINK_TO_DEATH_TRANSACTION,
     HIDL_UNLINK_TO_DEATH_TRANSACTION,
+    HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
     LAST_HIDL_TRANSACTION   = 0x00ffffff,
 };
 
@@ -61,6 +62,7 @@
     mReservedMethods.push_back(createSyspropsChangedMethod());
     mReservedMethods.push_back(createLinkToDeathMethod());
     mReservedMethods.push_back(createUnlinkToDeathMethod());
+    mReservedMethods.push_back(createSetHALInstrumentationMethod());
 }
 
 std::string Interface::typeName() const {
@@ -185,6 +187,44 @@
     );
 }
 
+Method *Interface::createSetHALInstrumentationMethod() const {
+    return new Method("setHALInstrumentation",
+            new std::vector<TypedVar *>() /*args */,
+            new std::vector<TypedVar *>() /*results */,
+            true /*oneway */,
+            new std::vector<Annotation *>(),
+            HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
+            {
+                {IMPL_HEADER,
+                    [this](auto &out) {
+                        // do nothing for base class.
+                        out << "return ::android::hardware::Void();\n";
+                    }
+                },
+                {IMPL_PROXY,
+                    [](auto &out) {
+                        out << "configureInstrumentation();\n";
+                        out << "return ::android::hardware::Void();\n";
+                    }
+                },
+                {IMPL_STUB,
+                    [](auto &out) {
+                        out << "configureInstrumentation();\n";
+                    }
+                },
+                {IMPL_PASSTHROUGH,
+                    [](auto &out) {
+                        out << "configureInstrumentation();\n";
+                        out << "return ::android::hardware::Void();\n";
+                    }
+                },
+            }, /*cppImpl */
+            { { IMPL_HEADER, [](auto & /*out*/) { /* javaImpl */
+                // Not support for Java Impl for now.
+            } } } /*javaImpl */
+    );
+}
+
 Method *Interface::createDescriptorChainMethod() const {
     VectorType *vecType = new VectorType();
     vecType->setElementType(new StringType());
diff --git a/Interface.h b/Interface.h
index 6cde462..0182818 100644
--- a/Interface.h
+++ b/Interface.h
@@ -113,6 +113,7 @@
     Method *createSyspropsChangedMethod() const;
     Method *createLinkToDeathMethod() const;
     Method *createUnlinkToDeathMethod() const;
+    Method *createSetHALInstrumentationMethod() const;
 
     DISALLOW_COPY_AND_ASSIGN(Interface);
 };
diff --git a/MemoryType.cpp b/MemoryType.cpp
index 857bf05..3243cd4 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -63,25 +63,16 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = (const ::android::hardware::hidl_memory *)"
+        out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer("
-            << "&"
+            << "readBuffer(&"
             << parentName
-            << ");\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n\n";
 
-        out << "if ("
-            << name
-            << " == nullptr) {\n";
-
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObjDeref
diff --git a/Method.h b/Method.h
index ac681a5..8a05ffc 100644
--- a/Method.h
+++ b/Method.h
@@ -38,7 +38,8 @@
 enum MethodImplType {
     IMPL_HEADER,
     IMPL_PROXY,
-    IMPL_STUB
+    IMPL_STUB,
+    IMPL_PASSTHROUGH,
 };
 
 using MethodImpl = std::map<MethodImplType, std::function<void(Formatter &)>>;
diff --git a/StringType.cpp b/StringType.cpp
index c366391..f093b65 100644
--- a/StringType.cpp
+++ b/StringType.cpp
@@ -78,25 +78,16 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = (const ::android::hardware::hidl_string *)"
+        out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer("
-            << "&"
+            << "readBuffer(&"
             << parentName
-            << ");\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n\n";
 
-        out << "if ("
-            << name
-            << " == nullptr) {\n";
-
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObjDeref
diff --git a/Type.cpp b/Type.cpp
index 54135e0..7e67702 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -274,34 +274,6 @@
     }
 }
 
-void Type::handleError2(Formatter &out, ErrorMode mode) const {
-    switch (mode) {
-        case ErrorMode_Goto:
-        {
-            out << "goto _hidl_error;\n";
-            break;
-        }
-
-        case ErrorMode_Break:
-        {
-            out << "break;\n";
-            break;
-        }
-
-        case ErrorMode_Ignore:
-        {
-            out << "/* ignoring _hidl_error! */";
-            break;
-        }
-
-        case ErrorMode_Return:
-        {
-            out << "return _hidl_err;\n";
-            break;
-        }
-    }
-}
-
 void Type::emitReaderWriterEmbeddedForTypeName(
         Formatter &out,
         const std::string &name,
diff --git a/Type.h b/Type.h
index c60ed8b..007b114 100644
--- a/Type.h
+++ b/Type.h
@@ -217,7 +217,6 @@
 
 protected:
     void handleError(Formatter &out, ErrorMode mode) const;
-    void handleError2(Formatter &out, ErrorMode mode) const;
 
     void emitReaderWriterEmbeddedForTypeName(
             Formatter &out,
diff --git a/VectorType.cpp b/VectorType.cpp
index ff21994..1c1271a 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -149,24 +149,16 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
-        out << name
-            << " = (const ::android::hardware::hidl_vec<"
-            << baseType
-            << "> *)"
+        out << "_hidl_err = "
             << parcelObjDeref
             << "readBuffer(&"
             << parentName
-            << ");\n\n";
+            << ", "
+            << " reinterpret_cast<const void **>("
+            << "&" << name
+            << "));\n\n";
 
-        out << "if (" << name << " == nullptr) {\n";
-
-        out.indent();
-
-        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
-        handleError2(out, mode);
-
-        out.unindent();
-        out << "}\n\n";
+        handleError(out, mode);
     } else {
         out << "_hidl_err = "
             << parcelObjDeref
diff --git a/generateCpp.cpp b/generateCpp.cpp
index a4af202..adde77d 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -537,6 +537,14 @@
     out << " {\n";
     out.indent();
 
+    if (method->isHidlReserved()
+        && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
+        method->cppImpl(IMPL_PASSTHROUGH, out);
+        out.unindent();
+        out << "}\n\n";
+        return OK;
+    }
+
     const bool returnsValue = !method->results().empty();
     const TypedVar *elidedReturn = method->canElideCallback();
 
@@ -1333,7 +1341,7 @@
     out << "}\n\n";
 
     if (iface->isIBase()) {
-        // BnBase has a constructor to initialize the HidlInstrumentor
+        // BnHwBase has a constructor to initialize the HidlInstrumentor
         // class properly.
         out << klassName
             << "::"
diff --git a/test/Android.bp b/test/Android.bp
index 0f783b8..36da370 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -1,5 +1,6 @@
 subdirs = [
     "vendor/1.0",
+    "java_test",
 ]
 
 cc_test {
diff --git a/test/java_test/Android.bp b/test/java_test/Android.bp
new file mode 100644
index 0000000..be0f89f
--- /dev/null
+++ b/test/java_test/Android.bp
@@ -0,0 +1,27 @@
+cc_binary {
+    name: "hidl_test_java_native",
+    srcs: ["hidl_test_java_native.cpp"],
+
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.tests.baz@1.0",
+        "android.hardware.tests.expression@1.0",
+        "android.hardware.tests.inheritance@1.0",
+    ],
+
+    static_libs: ["libgtest"],
+
+    compile_multilib: "both",
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            suffix: "64",
+        },
+    },
+}
diff --git a/test/java_test/Android.mk b/test/java_test/Android.mk
index ea8eebb..efe4558 100644
--- a/test/java_test/Android.mk
+++ b/test/java_test/Android.mk
@@ -22,7 +22,7 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES :=                \
     hidl_test_java_lib                          \
-    hidl_test_java_native
+    hidl_test_java_native                       \
 
 LOCAL_REQUIRED_MODULES :=                       \
     hidl_test_java_lib                          \
@@ -30,26 +30,3 @@
     android.hardware.tests.baz@1.0-java
 
 include $(BUILD_PREBUILT)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := hidl_test_java_native
-
-LOCAL_SRC_FILES := hidl_test_java_native.cpp
-
-LOCAL_SHARED_LIBRARIES :=                 \
-    libbase                               \
-    libhidlbase                           \
-    libhidltransport                      \
-    libhwbinder                           \
-    libutils                              \
-    android.hardware.tests.baz@1.0        \
-    android.hardware.tests.expression@1.0 \
-    android.hardware.tests.inheritance@1.0
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-include $(BUILD_EXECUTABLE)
diff --git a/test/java_test/hidl_test_java b/test/java_test/hidl_test_java
index e8876a2..a28a14f 100644
--- a/test/java_test/hidl_test_java
+++ b/test/java_test/hidl_test_java
@@ -1,21 +1,27 @@
 base=/system
 export CLASSPATH=$base/framework/hidl_test_java.jar:$base/framework/android.hardware.tests.baz@1.0-java.jar:$base/framework/android.hidl.base@1.0-java.jar
 
-# Test native server with Java client
-hidl_test_java_native -s &
-sleep 1
-NATIVE_PID=$!
-(app_process $base/bin com.android.commands.hidl_test_java.HidlTestJava -c     \
-    && echo "Java client => native server PASS")                               \
-    || echo "Java client => native server FAIL"
+for SIZE in 64 32; do
+    if [ -f /system/bin/hidl_test_java_native$SIZE ]; then
+        echo "Testing $SIZE bit native client/server"
 
-kill $NATIVE_PID
+        # Test native server with Java client
+        hidl_test_java_native$SIZE -s &
+        sleep 1
+        NATIVE_PID=$!
+        (app_process $base/bin com.android.commands.hidl_test_java.HidlTestJava -c     \
+            && echo "Java client => native server PASS")                               \
+            || echo "Java client => native server FAIL"
 
-# Test Java server with native client
-app_process $base/bin com.android.commands.hidl_test_java.HidlTestJava -s &
-NATIVE_PID=$!
-sleep 1
-(hidl_test_java_native -c && echo "native client => Java server PASS")         \
-    || echo "native client => Java server FAIL"
+        kill $NATIVE_PID 2>/dev/null
 
-kill $NATIVE_PID
+        # Test Java server with native client
+        app_process $base/bin com.android.commands.hidl_test_java.HidlTestJava -s &
+        NATIVE_PID=$!
+        sleep 1
+        (hidl_test_java_native$SIZE -c && echo "native client => Java server PASS")   \
+            || echo "native client => Java server FAIL"
+
+        kill $NATIVE_PID 2>/dev/null
+    fi
+done
diff --git a/test/main.cpp b/test/main.cpp
index 31d8bb7..83747be 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -13,9 +13,9 @@
 #include <android/hidl/token/1.0/ITokenManager.h>
 
 #include <android/hardware/tests/foo/1.0/IFoo.h>
-#include <android/hardware/tests/foo/1.0/BnSimple.h>
+#include <android/hardware/tests/foo/1.0/BnHwSimple.h>
 #include <android/hardware/tests/foo/1.0/BsSimple.h>
-#include <android/hardware/tests/foo/1.0/BpSimple.h>
+#include <android/hardware/tests/foo/1.0/BpHwSimple.h>
 #include <android/hardware/tests/bar/1.0/IBar.h>
 #include <android/hardware/tests/bar/1.0/IComplicated.h>
 #include <android/hardware/tests/inheritance/1.0/IFetcher.h>
@@ -702,6 +702,16 @@
     }
 }
 
+TEST_F(HidlTest, NullSharedMemory) {
+    hidl_memory memory{};
+
+    EXPECT_EQ(nullptr, memory.handle());
+
+    EXPECT_OK(memoryTest->haveSomeMemory(memory, [&](const hidl_memory &mem) {
+        EXPECT_EQ(nullptr, mem.handle());
+    }));
+}
+
 TEST_F(HidlTest, FooDoThisTest) {
     ALOGI("CLIENT call doThis.");
     EXPECT_OK(foo->doThis(1.0f));
@@ -762,20 +772,20 @@
 }
 
 TEST_F(HidlTest, WrapTest) {
-    using ::android::hardware::tests::foo::V1_0::BnSimple;
+    using ::android::hardware::tests::foo::V1_0::BnHwSimple;
     using ::android::hardware::tests::foo::V1_0::BsSimple;
-    using ::android::hardware::tests::foo::V1_0::BpSimple;
+    using ::android::hardware::tests::foo::V1_0::BpHwSimple;
     using ::android::hardware::HidlInstrumentor;
     nsecs_t now;
     int i = 0;
 
     now = systemTime();
-    new BnSimple(new Simple(1));
-    EXPECT_LT(systemTime() - now, 2000000) << "    for BnSimple(nonnull)";
+    new BnHwSimple(new Simple(1));
+    EXPECT_LT(systemTime() - now, 2000000) << "    for BnHwSimple(nonnull)";
 
     now = systemTime();
-    new BnSimple(nullptr);
-    EXPECT_LT(systemTime() - now, 2000000) << "    for BnSimple(null)";
+    new BnHwSimple(nullptr);
+    EXPECT_LT(systemTime() - now, 2000000) << "    for BnHwSimple(null)";
 
     now = systemTime();
     new BsSimple(new Simple(1));
@@ -786,8 +796,8 @@
     EXPECT_LT(systemTime() - now, 2000000) << "    for BsSimple(null)";
 
     now = systemTime();
-    new BpSimple(nullptr);
-    EXPECT_LT(systemTime() - now, 2000000) << "    for BpSimple(null)";
+    new BpHwSimple(nullptr);
+    EXPECT_LT(systemTime() - now, 2000000) << "    for BpHwSimple(null)";
 
     now = systemTime();
     new ::android::hardware::HidlInstrumentor("");
diff --git a/test/vendor/1.0/Android.bp b/test/vendor/1.0/Android.bp
index 7f3aa3e..4307cea 100644
--- a/test/vendor/1.0/Android.bp
+++ b/test/vendor/1.0/Android.bp
@@ -5,9 +5,11 @@
     tools: ["hidl-gen"],
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -rtests:system/tools/hidl/test/ -randroid.hidl:system/libhidl/transport tests.vendor@1.0",
     srcs: [
+        "types.hal",
         "IVendor.hal",
     ],
     out: [
+        "tests/vendor/1.0/types.cpp",
         "tests/vendor/1.0/VendorAll.cpp",
     ],
 }
@@ -17,13 +19,15 @@
     tools: ["hidl-gen"],
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -rtests:system/tools/hidl/test/ -randroid.hidl:system/libhidl/transport tests.vendor@1.0",
     srcs: [
+        "types.hal",
         "IVendor.hal",
     ],
     out: [
+        "tests/vendor/1.0/types.h",
         "tests/vendor/1.0/IVendor.h",
         "tests/vendor/1.0/IHwVendor.h",
-        "tests/vendor/1.0/BnVendor.h",
-        "tests/vendor/1.0/BpVendor.h",
+        "tests/vendor/1.0/BnHwVendor.h",
+        "tests/vendor/1.0/BpHwVendor.h",
         "tests/vendor/1.0/BsVendor.h",
     ],
 }
diff --git a/test/vendor/1.0/Android.mk b/test/vendor/1.0/Android.mk
new file mode 100644
index 0000000..ee341d4
--- /dev/null
+++ b/test/vendor/1.0/Android.mk
@@ -0,0 +1,40 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tests.vendor@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/tests/vendor/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVendor.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava-constants \
+        -rtests:system/tools/hidl/test/ \
+        -randroid.hidl:system/libhidl/transport \
+        tests.vendor@1.0
+
+$(GEN):
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/test/vendor/1.0/types.hal b/test/vendor/1.0/types.hal
new file mode 100644
index 0000000..511389e
--- /dev/null
+++ b/test/vendor/1.0/types.hal
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.vendor@1.0;
+
+enum Bar : uint32_t {
+    A
+};
+
+/* WARNING:
+ *
+ * @export is used to expose this enumeration in a C header using -Lexport-header.
+ *
+ * It should only be used to make a backwards compatible header definition so that
+ * constant values defined in a .hal file can be used in a C library.
+ *
+ * export_parent below is used to test the functionality of export_parent. Typically,
+ * you would only use it when inheriting from a parent type. Obviously if name is not empty,
+ * then export_parent isn't required.
+ */
+@export(name="") // export_parent is implicitly true
+enum Foo : Bar {
+    B,
+    C
+};
+
+@export(name="", export_parent="false")
+enum FooToo : Foo {
+    D
+};
\ No newline at end of file
diff --git a/test/vendor/1.0/update-base.sh b/test/vendor/1.0/update-base.sh
new file mode 100755
index 0000000..8c7d688
--- /dev/null
+++ b/test/vendor/1.0/update-base.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+
+# WARNING: vendor-base is placed here only for testing.
+# It should typically be created elsewhere.
+
+options="-Lexport-header \
+         -r tests:system/tools/hidl/test/\
+         -r android.hidl:system/libhidl/transport"
+
+hidl-gen $options \
+         -o system/tools/hidl/test/vendor/1.0/vendor-base.h \
+         tests.vendor@1.0
\ No newline at end of file
diff --git a/test/vendor/1.0/vendor-base.h b/test/vendor/1.0/vendor-base.h
new file mode 100644
index 0000000..b9775f4
--- /dev/null
+++ b/test/vendor/1.0/vendor-base.h
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: tests.vendor@1.0
+
+#ifndef HIDL_GENERATED_TESTS_VENDOR_V1_0_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_TESTS_VENDOR_V1_0_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    A = 0u, // 0
+    B = 1u, // 1
+    C = 2u, // 2
+};
+
+enum {
+    D = 3u, // 3
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // HIDL_GENERATED_TESTS_VENDOR_V1_0_EXPORTED_CONSTANTS_H_