Merge changes from topic "java_native_handles"

* changes:
  Testing native handles with non-zero FDs
  Augmenting hidl-gen to support native handles in Java
diff --git a/Annotation.cpp b/Annotation.cpp
index e5a66b0..438cff6 100644
--- a/Annotation.cpp
+++ b/Annotation.cpp
@@ -84,24 +84,17 @@
     const std::string& name, std::vector<ConstantExpression*>* values)
     : AnnotationParam(name), mValues(values) {}
 
-std::string convertToString(const ConstantExpression* value) {
-    if (value->descriptionIsTrivial()) {
-        return value->value();
-    }
-    return value->value() + " /* " + value->description() + " */";
-}
-
 std::vector<std::string> ConstantExpressionAnnotationParam::getValues() const {
     std::vector<std::string> ret;
     for (const auto* value : *mValues) {
-        ret.push_back(convertToString(value));
+        ret.push_back(value->value());
     };
     return ret;
 }
 
 std::string ConstantExpressionAnnotationParam::getSingleValue() const {
     CHECK_EQ(mValues->size(), 1u) << mName << " requires one value but has multiple";
-    return convertToString(mValues->at(0));
+    return mValues->at(0)->value();
 }
 
 std::vector<const ConstantExpression*> ConstantExpressionAnnotationParam::getConstantExpressions()
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 44446a8..9835968 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -97,14 +97,7 @@
     std::string arrayType = space + "hidl_array<" + base;
 
     for (size_t i = 0; i < mSizes.size(); ++i) {
-        arrayType += ", ";
-        arrayType += mSizes[i]->cppValue();
-
-        if (!mSizes[i]->descriptionIsTrivial()) {
-            arrayType += " /* ";
-            arrayType += mSizes[i]->description();
-            arrayType += " */";
-        }
+        arrayType += ", " + mSizes[i]->cppValue();
     }
 
     arrayType += ">";
@@ -142,12 +135,8 @@
 
         if (forInitializer) {
             base += mSizes[i]->javaValue();
-        }
-
-        if (!forInitializer || !mSizes[i]->descriptionIsTrivial()) {
-            if (forInitializer)
-                base += " ";
-            base += "/* " + mSizes[i]->description() + " */";
+        } else {
+            base += "/* " + mSizes[i]->expression() + " */";
         }
 
         base += "]";
@@ -555,7 +544,7 @@
 
 void ArrayType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    out << "vector_size: " << mSizes[0]->value() << "\n";
+    out << "vector_size: " << mSizes[0]->rawValue() << "\n";
     out << "vector_value: {\n";
     out.indent();
     // Simple array case.
@@ -564,7 +553,7 @@
     } else {  // Multi-dimension array case.
         for (size_t index = 1; index < mSizes.size(); index++) {
             out << "type: " << getVtsType() << "\n";
-            out << "vector_size: " << mSizes[index]->value() << "\n";
+            out << "vector_size: " << mSizes[index]->rawValue() << "\n";
             out << "vector_value: {\n";
             out.indent();
             if (index == mSizes.size() - 1) {
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index 97e1317..a025dd2 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -173,7 +173,7 @@
 
     CHECK(!expr.empty());
     CHECK(isSupported(kind));
-    mTrivialDescription = true;
+    mTrivialDescription = std::to_string(value) == expr;
     mExpr = expr;
     mValueKind = kind;
     mValue = value;
@@ -254,7 +254,7 @@
     CHECK(mUnary->isEvaluated());
     mIsEvaluated = true;
 
-    mExpr = std::string("(") + mOp + mUnary->description() + ")";
+    mExpr = std::string("(") + mOp + mUnary->mExpr + ")";
     mValueKind = mUnary->mValueKind;
 
 #define CASE_UNARY(__type__)                                          \
@@ -270,7 +270,7 @@
     CHECK(mRval->isEvaluated());
     mIsEvaluated = true;
 
-    mExpr = std::string("(") + mLval->description() + " " + mOp + " " + mRval->description() + ")";
+    mExpr = std::string("(") + mLval->mExpr + " " + mOp + " " + mRval->mExpr + ")";
 
     bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP;
 
@@ -330,8 +330,7 @@
     CHECK(mFalseVal->isEvaluated());
     mIsEvaluated = true;
 
-    mExpr = std::string("(") + mCond->description() + "?" + mTrueVal->description() + ":" +
-            mFalseVal->description() + ")";
+    mExpr = std::string("(") + mCond->mExpr + "?" + mTrueVal->mExpr + ":" + mFalseVal->mExpr + ")";
 
     // note: for ?:, unlike arithmetic ops, integral promotion is not processed.
     mValueKind = usualArithmeticConversion(mTrueVal->mValueKind, mFalseVal->mValueKind);
@@ -362,28 +361,16 @@
     return ret;
 }
 
-const std::string& ConstantExpression::description() const {
-    CHECK(isEvaluated());
-    return mExpr;
-}
-
-bool ConstantExpression::descriptionIsTrivial() const {
-    CHECK(isEvaluated());
-    return mTrivialDescription;
-}
-
 std::string ConstantExpression::value() const {
-    CHECK(isEvaluated());
-    return rawValue(mValueKind);
+    return value(mValueKind);
 }
 
 std::string ConstantExpression::value(ScalarType::Kind castKind) const {
     CHECK(isEvaluated());
-    return rawValue(castKind);
+    return rawValue(castKind) + descriptionSuffix();
 }
 
 std::string ConstantExpression::cppValue() const {
-    CHECK(isEvaluated());
     return cppValue(mValueKind);
 }
 
@@ -399,35 +386,60 @@
     // -(uint64_t)9223372036854775808 == 9223372036854775808 could not
     // be narrowed to int64_t.
     if(castKind == SK(INT64) && (int64_t)mValue == INT64_MIN) {
-        return "static_cast<" +
-               ScalarType(SK(INT64), nullptr /* parent */).getCppStackType()  // "int64_t"
-               + ">(" + literal + "ull)";
+        literal = "static_cast<" +
+                  ScalarType(SK(INT64), nullptr /* parent */).getCppStackType()  // "int64_t"
+                  + ">(" + literal + "ull)";
+    } else {
+        // add suffix if necessary.
+        if (castKind == SK(UINT32) || castKind == SK(UINT64)) literal += "u";
+        if (castKind == SK(UINT64) || castKind == SK(INT64)) literal += "ll";
     }
 
-    // add suffix if necessary.
-    if(castKind == SK(UINT32) || castKind == SK(UINT64)) literal += "u";
-    if(castKind == SK(UINT64) || castKind == SK(INT64)) literal += "ll";
-    return literal;
+    return literal + descriptionSuffix();
 }
 
 std::string ConstantExpression::javaValue() const {
-    CHECK(isEvaluated());
     return javaValue(mValueKind);
 }
 
 std::string ConstantExpression::javaValue(ScalarType::Kind castKind) const {
     CHECK(isEvaluated());
+    std::string literal;
+
     switch(castKind) {
-        case SK(UINT64): return rawValue(SK(INT64)) + "L";
-        case SK(INT64):  return rawValue(SK(INT64)) + "L";
-        case SK(UINT32): return rawValue(SK(INT32));
-        case SK(UINT16): return rawValue(SK(INT16));
-        case SK(UINT8) : return rawValue(SK(INT8));
+        case SK(UINT64):
+            literal = rawValue(SK(INT64)) + "L";
+            break;
+        case SK(INT64):
+            literal = rawValue(SK(INT64)) + "L";
+            break;
+        case SK(UINT32):
+            literal = rawValue(SK(INT32));
+            break;
+        case SK(UINT16):
+            literal = rawValue(SK(INT16));
+            break;
+        case SK(UINT8):
+            literal = rawValue(SK(INT8));
+            break;
         case SK(BOOL)  :
-            return this->cast<bool>() ? "true" : "false";
-        default: break;
+            literal = this->cast<bool>() ? "true" : "false";
+            break;
+        default:
+            literal = rawValue(castKind);
+            break;
     }
-    return rawValue(castKind);
+
+    return literal + descriptionSuffix();
+}
+
+const std::string& ConstantExpression::expression() const {
+    CHECK(isEvaluated());
+    return mExpr;
+}
+
+std::string ConstantExpression::rawValue() const {
+    return rawValue(mValueKind);
 }
 
 std::string ConstantExpression::rawValue(ScalarType::Kind castKind) const {
@@ -447,6 +459,17 @@
     SWITCH_KIND(mValueKind, CASE_CAST_T, SHOULD_NOT_REACH(); return 0; );
 }
 
+std::string ConstantExpression::descriptionSuffix() const {
+    CHECK(isEvaluated());
+
+    if (!mTrivialDescription) {
+        CHECK(!mExpr.empty());
+
+        return " /* " + mExpr + " */";
+    }
+    return "";
+}
+
 size_t ConstantExpression::castSizeT() const {
     CHECK(isEvaluated());
     return this->cast<size_t>();
diff --git a/ConstantExpression.h b/ConstantExpression.h
index 9784885..c5bdbe3 100644
--- a/ConstantExpression.h
+++ b/ConstantExpression.h
@@ -93,11 +93,11 @@
 
     /* Returns true iff the value has already been evaluated. */
     bool isEvaluated() const;
-    /* Evaluated result in a string form. */
+    /* Evaluated result in a string form with comment if applicable. */
     std::string value() const;
-    /* Evaluated result in a string form. */
+    /* Evaluated result in a string form with comment if applicable. */
     std::string cppValue() const;
-    /* Evaluated result in a string form. */
+    /* Evaluated result in a string form with comment if applicable. */
     std::string javaValue() const;
     /* Evaluated result in a string form, with given contextual kind. */
     std::string value(ScalarType::Kind castKind) const;
@@ -105,10 +105,10 @@
     std::string cppValue(ScalarType::Kind castKind) const;
     /* Evaluated result in a string form, with given contextual kind. */
     std::string javaValue(ScalarType::Kind castKind) const;
-    /* Formatted expression with type. */
-    const std::string& description() const;
-    /* See mTrivialDescription */
-    bool descriptionIsTrivial() const;
+
+    /* The expression representing this value for use in comments when the value is not needed */
+    const std::string& expression() const;
+
     /* Return a ConstantExpression that is 1 plus the original. */
     std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
 
@@ -118,6 +118,14 @@
     // Post parse passes must be proceeded during owner package parsin
     void setPostParseCompleted();
 
+    /*
+     * Helper function for all cpp/javaValue methods.
+     * Returns a plain string (without any prefixes or suffixes, just the
+     * digits) converted from mValue.
+     */
+    std::string rawValue() const;
+    std::string rawValue(ScalarType::Kind castKind) const;
+
    private:
     /* If the result value has been evaluated. */
     bool mIsEvaluated = false;
@@ -133,11 +141,9 @@
     bool mIsPostParseCompleted = false;
 
     /*
-     * Helper function for all cpp/javaValue methods.
-     * Returns a plain string (without any prefixes or suffixes, just the
-     * digits) converted from mValue.
+     * Helper function, gives suffix comment to add to value/cppValue/javaValue
      */
-    std::string rawValue(ScalarType::Kind castKind) const;
+    std::string descriptionSuffix() const;
 
     /*
      * Return the value casted to the given type.
@@ -156,13 +162,11 @@
 
 struct LiteralConstantExpression : public ConstantExpression {
     LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
+    LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
     void evaluate() override;
     std::vector<const ConstantExpression*> getConstantExpressions() const override;
 
     static LiteralConstantExpression* tryParse(const std::string& value);
-
-private:
-    LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
 };
 
 struct UnaryConstantExpression : public ConstantExpression {
diff --git a/EnumType.cpp b/EnumType.cpp
index 86467c7..e0057ae 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -260,16 +260,7 @@
 
             std::string value = entry->cppValue(scalarType->getKind());
             CHECK(!value.empty()); // use autofilled values for c++.
-            out << " = " << value;
-
-            out << ",";
-
-            std::string comment = entry->comment();
-            if (!comment.empty()) {
-                out << " // " << comment;
-            }
-
-            out << "\n";
+            out << " = " << value << ",\n";
         }
     }
 
@@ -485,16 +476,7 @@
             // javaValue will make the number signed.
             std::string value = entry->javaValue(scalarType->getKind());
             CHECK(!value.empty()); // use autofilled values for java.
-            out << value;
-
-            out << ";";
-
-            std::string comment = entry->comment();
-            if (!comment.empty()) {
-                out << " // " << comment;
-            }
-
-            out << "\n";
+            out << value << ";\n";
         }
     }
 
@@ -562,7 +544,7 @@
             out << "scalar_value: {\n";
             out.indent();
             // use autofilled values for vts.
-            std::string value = entry->value(scalarType->getKind());
+            std::string value = entry->rawValue(scalarType->getKind());
             CHECK(!value.empty());
             out << mStorageType->resolveToScalarType()->getVtsScalarType()
                 << ": "
@@ -703,16 +685,7 @@
                 // javaValue will make the number signed.
                 std::string value = entry->javaValue(scalarType->getKind());
                 CHECK(!value.empty()); // use autofilled values for java.
-                out << value;
-
-                out << ";";
-
-                std::string comment = entry->comment();
-                if (!comment.empty()) {
-                    out << " // " << comment;
-                }
-
-                out << "\n";
+                out << value << ";\n";
             }
         }
 
@@ -741,16 +714,7 @@
 
             std::string value = entry->cppValue(scalarType->getKind());
             CHECK(!value.empty()); // use autofilled values for c++.
-            out << " = " << value;
-
-            out << ",";
-
-            std::string comment = entry->comment();
-            if (!comment.empty()) {
-                out << " // " << comment;
-            }
-
-            out << "\n";
+            out << " = " << value << ",\n";
         }
     }
 
@@ -773,9 +737,9 @@
     return mName;
 }
 
-std::string EnumValue::value(ScalarType::Kind castKind) const {
+std::string EnumValue::rawValue(ScalarType::Kind castKind) const {
     CHECK(mValue != nullptr);
-    return mValue->value(castKind);
+    return mValue->rawValue(castKind);
 }
 
 std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
@@ -787,12 +751,6 @@
     return mValue->javaValue(castKind);
 }
 
-std::string EnumValue::comment() const {
-    CHECK(mValue != nullptr);
-    if (mValue->descriptionIsTrivial()) return "";
-    return mValue->description();
-}
-
 ConstantExpression *EnumValue::constExpr() const {
     CHECK(mValue != nullptr);
     return mValue;
diff --git a/EnumType.h b/EnumType.h
index c9b719e..2854c25 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -140,10 +140,9 @@
     EnumValue(const char* name, ConstantExpression* value, const Location& location);
 
     std::string name() const;
-    std::string value(ScalarType::Kind castKind) const;
+    std::string rawValue(ScalarType::Kind castKind) const;
     std::string cppValue(ScalarType::Kind castKind) const;
     std::string javaValue(ScalarType::Kind castKind) const;
-    std::string comment() const;
     void autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type);
     ConstantExpression* constExpr() const override;
 
diff --git a/Interface.cpp b/Interface.cpp
index 8370c36..44eb872 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -68,6 +68,9 @@
     LAST_HIDL_TRANSACTION   = 0x0fffffff,
 };
 
+const std::unique_ptr<ConstantExpression> Interface::FLAG_ONE_WAY =
+    std::make_unique<LiteralConstantExpression>(ScalarType::KIND_UINT32, 0x01, "oneway");
+
 Interface::Interface(const char* localName, const FQName& fullName, const Location& location,
                      Scope* parent, const Reference<Type>& superType, const Hash* fileHash)
     : Scope(localName, fullName, location, parent), mSuperType(superType), mFileHash(fileHash) {}
diff --git a/Interface.h b/Interface.h
index 005beff..2604c77 100644
--- a/Interface.h
+++ b/Interface.h
@@ -22,6 +22,7 @@
 
 #include <hidl-hash/Hash.h>
 
+#include "ConstantExpression.h"
 #include "Reference.h"
 #include "Scope.h"
 
@@ -31,10 +32,7 @@
 struct InterfaceAndMethod;
 
 struct Interface : public Scope {
-    enum {
-        /////////////////// Flag(s) - DO NOT CHANGE
-        FLAG_ONEWAY = 0x00000001,
-    };
+    const static std::unique_ptr<ConstantExpression> FLAG_ONE_WAY;
 
     Interface(const char* localName, const FQName& fullName, const Location& location,
               Scope* parent, const Reference<Type>& superType, const Hash* fileHash);
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 5bf1ee5..a2889b5 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -1093,7 +1093,7 @@
         << " */, _hidl_data, &_hidl_reply";
 
     if (method->isOneway()) {
-        out << ", " << Interface::FLAG_ONEWAY << " /* oneway */";
+        out << ", " << Interface::FLAG_ONE_WAY->cppValue();
     }
     out << ");\n";
 
@@ -1324,8 +1324,8 @@
 
         out.indent();
 
-        out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONEWAY
-            << " /* oneway */;\n";
+        out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
+            << ";\n";
         out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
         out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
 
diff --git a/generateJava.cpp b/generateJava.cpp
index 9b2f593..fcc1823 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -383,7 +383,7 @@
                 << " */, _hidl_request, _hidl_reply, ";
 
             if (method->isOneway()) {
-                out << Interface::FLAG_ONEWAY << " /* oneway */";
+                out << Interface::FLAG_ONE_WAY->javaValue();
             } else {
                 out << "0 /* flags */";
             }
@@ -535,8 +535,8 @@
 
         out.indent();
 
-        out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONEWAY
-            << " /* oneway */) != 0\n;";
+        out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONE_WAY->javaValue()
+            << ") != 0;\n";
         out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
         out.block([&] {
             out << "_hidl_reply.writeStatus(" << UNKNOWN_ERROR << ");\n";
diff --git a/test/error_test/hidl_error_test.sh b/test/error_test/hidl_error_test.sh
index 2f5d522..d747776 100755
--- a/test/error_test/hidl_error_test.sh
+++ b/test/error_test/hidl_error_test.sh
@@ -1,12 +1,17 @@
 #!/bin/bash
 
-if [ $# -ne 1 ]; then
+if [ $# -gt 1 ]; then
     echo "usage: hidl_error_test.sh hidl-gen_path"
     exit 1
 fi
 
-readonly HIDL_GEN_PATH=$1
-readonly HIDL_ERROR_TEST_DIR="$ANDROID_BUILD_TOP/system/tools/hidl/test/error_test"
+readonly HIDL_GEN_PATH=${1:-hidl-gen}
+readonly HIDL_ERROR_TEST_DIR="${ANDROID_BUILD_TOP:-.}/system/tools/hidl/test/error_test"
+
+if [ ! -d $HIDL_ERROR_TEST_DIR ]; then
+    echo "cannot find test directory: $HIDL_ERROR_TEST_DIR"
+    exit 1
+fi
 
 for dir in $(ls -d $HIDL_ERROR_TEST_DIR/*/); do
   package=$(basename $dir)