Merge "Properly determine if the current package is java compatible or not"
diff --git a/Interface.cpp b/Interface.cpp
index cd9dcd3..4d22c5c 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -31,6 +31,26 @@
 }
 
 void Interface::addMethod(Method *method) {
+    /* It is very important that these values NEVER change. These values
+     * must remain unchanged over the lifetime of android. This is
+     * because the framework on a device will be updated independently of
+     * the hals on a device. If the hals are compiled with one set of
+     * transaction values, and the framework with another, then the
+     * interface between them will be destroyed, and the device will not
+     * work.
+     */
+    size_t serial = 1; // hardware::IBinder::FIRST_CALL_TRANSACTION;
+
+    serial += methods().size();
+
+    const Interface *ancestor = mSuperType;
+    while (ancestor != nullptr) {
+        serial += ancestor->methods().size();
+        ancestor = ancestor->superType();
+    }
+
+    method->setSerialId(serial);
+
     mMethods.push_back(method);
 }
 
diff --git a/Method.cpp b/Method.cpp
index 7d7717a..95a688a 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -52,6 +52,14 @@
     return *mAnnotations;
 }
 
+void Method::setSerialId(size_t serial) {
+    mSerial = serial;
+}
+
+size_t Method::getSerialId() const {
+    return mSerial;
+}
+
 void Method::generateCppSignature(Formatter &out,
                                   const std::string &className,
                                   bool specifyNamespaces) const {
diff --git a/Method.h b/Method.h
index aba7755..3c84914 100644
--- a/Method.h
+++ b/Method.h
@@ -43,6 +43,9 @@
     bool isOneway() const { return mOneway; }
     const std::vector<Annotation *> &annotations() const;
 
+    void setSerialId(size_t serial);
+    size_t getSerialId() const;
+
     void generateCppSignature(Formatter &out,
                               const std::string &className,
                               bool specifyNamespaces) const;
@@ -59,6 +62,7 @@
 
 private:
     std::string mName;
+    size_t mSerial = 0;
     std::vector<TypedVar *> *mArgs;
     std::vector<TypedVar *> *mResults;
     bool mOneway;
diff --git a/Scope.cpp b/Scope.cpp
index c4d07c2..8caf9c9 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -115,20 +115,6 @@
     return false;
 }
 
-std::string Scope::pickUniqueAnonymousName() const {
-    static size_t sNextID = 0;
-
-    for (;;) {
-        std::string anonName = "_hidl_Anon_" + std::to_string(sNextID++);
-
-        auto it = mTypeIndexByName.find(anonName);
-
-        if (it == mTypeIndexByName.end()) {
-            return anonName;
-        }
-    }
-}
-
 status_t Scope::emitTypeDeclarations(Formatter &out) const {
     for (size_t i = 0; i < mTypes.size(); ++i) {
         status_t err = mTypes[i]->emitTypeDeclarations(out);
diff --git a/Scope.h b/Scope.h
index fd6074c..8d26cac 100644
--- a/Scope.h
+++ b/Scope.h
@@ -49,8 +49,6 @@
     bool containsSingleInterface(std::string *ifaceName) const;
     bool containsInterfaces() const;
 
-    std::string pickUniqueAnonymousName() const;
-
     status_t emitTypeDeclarations(Formatter &out) const override;
     status_t emitGlobalTypeDeclarations(Formatter &out) const override;
 
diff --git a/generateCpp.cpp b/generateCpp.cpp
index f8a5b1a..c514714 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -24,7 +24,6 @@
 #include "Scope.h"
 
 #include <algorithm>
-#include <hidl-util/StringHelper.h>
 #include <hidl-util/Formatter.h>
 #include <android-base/logging.h>
 #include <string>
@@ -369,35 +368,6 @@
 
     out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
 
-    out << "enum Call {\n";
-    out.indent();
-
-    bool first = true;
-    for (const auto &method : iface->methods()) {
-        out << StringHelper::Uppercase(method->name());
-
-        if (first) {
-            out << " = ";
-            if (superType != NULL) {
-                out << superType->fqName().cppNamespace()
-                    << "::IHw"
-                    << superType->getBaseName()
-                    << "::Call::CallCount";
-            } else {
-                out << "::android::hardware::IBinder::FIRST_CALL_TRANSACTION";
-            }
-
-            first = false;
-        }
-
-        out << ",\n";
-    }
-
-    out << "CallCount\n";
-
-    out.unindent();
-    out << "};\n\n";
-
     out.unindent();
 
     out << "};\n\n";
@@ -1046,12 +1016,11 @@
             }
 
             out << "_hidl_err = remote()->transact("
-                      << superInterface->fqName().cppNamespace()
-                      << "::IHw"
-                      << superInterface->getBaseName()
-                      << "::Call::"
-                      << StringHelper::Uppercase(method->name())
-                      << ", _hidl_data, &_hidl_reply";
+                << method->getSerialId()
+                << " /* "
+                << method->name()
+                << " */, _hidl_data, &_hidl_reply";
+
             if (method->isOneway()) {
                 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
             }
@@ -1212,12 +1181,10 @@
 
         for (const auto &method : superInterface->methods()) {
             out << "case "
-                << superInterface->fqName().cppNamespace()
-                << "::IHw"
-                << superInterface->getBaseName()
-                << "::Call::"
-                << StringHelper::Uppercase(method->name())
-                << ":\n{\n";
+                << method->getSerialId()
+                << " /* "
+                << method->name()
+                << " */:\n{\n";
 
             out.indent();
 
@@ -1644,7 +1611,7 @@
         out.unindent();
         out << "}\n";
 
-        out << "return Status();\n";
+        out << "return ::android::hardware::Status();\n";
 
         out.unindent();
         out << "}\n\n";
diff --git a/generateJava.cpp b/generateJava.cpp
index e9958b6..1e0c478 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -21,7 +21,6 @@
 #include "Method.h"
 #include "Scope.h"
 
-#include <hidl-util/StringHelper.h>
 #include <hidl-util/Formatter.h>
 #include <android-base/logging.h>
 
@@ -223,36 +222,6 @@
         return err;
     }
 
-    const std::string base = (superType != NULL)
-        ? (superType->fullJavaName() + ".kOpEnd")
-        : "IHwBinder.FIRST_CALL_TRANSACTION";
-
-    bool first = true;
-    size_t index = 0;
-    for (const auto &method : iface->methods()) {
-        out << "public static final int kOp_"
-            << StringHelper::Uppercase(method->name())
-            << " = "
-            << base;
-
-        if (!first) {
-            out << " + " << index;
-        }
-
-        out << ";\n";
-
-        ++index;
-        first = false;
-    }
-
-    out << "public static final int kOpEnd = "
-        << base
-        << " + "
-        << index
-        << ";";
-
-    out << "\n\n";
-
     for (const auto &method : iface->methods()) {
         const bool returnsValue = !method->results().empty();
         const bool needsCallback = method->results().size() > 1;
@@ -373,9 +342,11 @@
             }
 
             out << "\nHwParcel reply = new HwParcel();\n"
-                << "mRemote.transact(kOp_"
-                << StringHelper::Uppercase(method->name())
-                << ", request, reply, ";
+                << "mRemote.transact("
+                << method->getSerialId()
+                << " /* "
+                << method->name()
+                << " */, request, reply, ";
 
             if (method->isOneway()) {
                 out << "IHwBinder.FLAG_ONEWAY";
@@ -476,11 +447,10 @@
             const bool needsCallback = method->results().size() > 1;
 
             out << "case "
-                << superInterface->fullJavaName()
-                << ".kOp_"
-                <<
-                StringHelper::Uppercase(method->name())
-                << ":\n{\n";
+                << method->getSerialId()
+                << " /* "
+                << method->name()
+                << " */:\n{\n";
 
             out.indent();
 
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 9163aa3..1b6ae5c 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -98,13 +98,11 @@
 /* Precedence level 3, RTL; but we have to use %left here */
 %left UNARY_MINUS UNARY_PLUS '!' '~'
 
-%type<str> optIdentifier package
+%type<str> package
 %type<fqName> fqname
 %type<type> fqtype
 
 %type<type> type opt_storage_type
-%type<type> enum_declaration
-%type<type> struct_or_union_declaration
 %type<type> opt_extends
 %type<type> type_declaration_body interface_declaration typedef_declaration
 %type<type> named_struct_or_union_declaration named_enum_declaration
@@ -560,40 +558,6 @@
       }
     ;
 
-struct_or_union_declaration
-    : struct_or_union_keyword optIdentifier
-      {
-          const char *localName = $2;
-          std::string anonName;
-          if (localName == nullptr) {
-              anonName = ast->scope()->pickUniqueAnonymousName();
-              localName = anonName.c_str();
-          }
-
-          CompoundType *container = new CompoundType($1, localName);
-          ast->enterScope(container);
-      }
-      struct_or_union_body
-      {
-          CompoundType *container = static_cast<CompoundType *>(ast->scope());
-
-          std::string errorMsg;
-          if (!container->setFields($4, &errorMsg)) {
-              std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
-              YYERROR;
-          }
-
-          ast->leaveScope();
-
-          if (!ast->addScopedType(container, &errorMsg)) {
-              std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
-              YYERROR;
-          }
-
-          $$ = container;
-      }
-    ;
-
 struct_or_union_body
     : '{' field_declarations '}' { $$ = $2; }
     ;
@@ -624,8 +588,8 @@
     ;
 
 compound_declaration
-    : struct_or_union_declaration { $$ = $1; }
-    | enum_declaration { $$ = $1; }
+    : named_struct_or_union_declaration { $$ = $1; }
+    | named_enum_declaration { $$ = $1; }
     ;
 
 opt_storage_type
@@ -668,46 +632,6 @@
       }
     ;
 
-enum_declaration
-    : ENUM
-      {
-          std::string anonName = ast->scope()->pickUniqueAnonymousName();
-          ast->enterScope(new EnumType(anonName.c_str()));
-      }
-      enum_declaration_body
-      {
-
-          EnumType *enumType = static_cast<EnumType *>(ast->scope());
-          ast->leaveScope();
-
-          std::string errorMsg;
-          if (!ast->addScopedType(enumType, &errorMsg)) {
-              // This should never fail.
-              std::cerr << "ERROR: " << errorMsg << "\n";
-              YYERROR;
-          }
-
-          $$ = enumType;
-      }
-    | ENUM IDENTIFIER opt_storage_type
-      {
-          ast->enterScope(new EnumType($2, $3));
-      }
-      enum_declaration_body
-      {
-          EnumType *enumType = static_cast<EnumType *>(ast->scope());
-          ast->leaveScope();
-
-          std::string errorMsg;
-          if (!ast->addScopedType(enumType, &errorMsg)) {
-              std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
-              YYERROR;
-          }
-
-          $$ = enumType;
-      }
-    ;
-
 enum_declaration_body
     : '{' enum_values opt_comma '}' { $$ = $2; }
     ;
@@ -774,11 +698,6 @@
     | INTERFACE { $$ = new GenericBinder; }
     ;
 
-optIdentifier
-    : /* empty */ { $$ = NULL; }
-    | IDENTIFIER { $$ = $1; }
-    ;
-
 %%
 
 #include <android-base/logging.h>
diff --git a/test/main.cpp b/test/main.cpp
index 2f6680f..338eaf9 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -569,6 +569,7 @@
 
 struct Bar : public IBar {
     Return<void> doThis(float param) override;
+    Return<void> doThis(uint32_t param) override;
 
     Return<int32_t> doThatAndReturnSomething(int64_t param) override;
 
@@ -635,6 +636,11 @@
     return Void();
 }
 
+Return<void> Bar::doThis(uint32_t param) {
+    ALOGI("SERVER(Bar) doThis (int) (%d)", param);
+    return Void();
+}
+
 Return<int32_t> Bar::doThatAndReturnSomething(
         int64_t param) {
     LOG(INFO) << "SERVER(Bar) doThatAndReturnSomething(" << param << ")";
@@ -1124,6 +1130,13 @@
     EXPECT_EQ(true, true);
 }
 
+TEST_F(HidlTest, FooDoThisIntTest) {
+    ALOGI("CLIENT call doThis (int).");
+    EXPECT_OK(foo->doThis(42u));
+    ALOGI("CLIENT doThis (int) returned.");
+    EXPECT_EQ(true, true);
+}
+
 TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
     ALOGI("CLIENT call doThatAndReturnSomething.");
     int32_t result = foo->doThatAndReturnSomething(2.0f);
@@ -1458,6 +1471,11 @@
                 }));
 }
 
+TEST_F(HidlTest, FooNullNativeHandleTest) {
+    Abc xyz;
+    xyz.z = nullptr;
+    EXPECT_FAIL(foo->haveATypeFromAnotherFile(xyz));
+}
 
 TEST_F(HidlTest, FooNonNullCallbackTest) {
     hidl_array<hidl_string, 5, 3> in;