Encode hidl_version in each generated interface.

Each generated interface will have a constexpr encoding
the package version. Additionally, there's a client-facing
getInterfaceVersion() method; while for now it always returns
the static version, this is not always correct: in case this
interface has a transport that goes to a remote implementation,
the version needs to be retrieved from that implementation
instead. This depends on other changes and will be added with them.

Bug: 31297066
Change-Id: I15b7f5ccf2dbfa25acfd385c68e8ae1f3e782ade
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/FQName.cpp b/FQName.cpp
index b031c6f..2504ef5 100644
--- a/FQName.cpp
+++ b/FQName.cpp
@@ -230,25 +230,37 @@
         bool cpp_compatible) const {
     getPackageComponents(components);
 
-    const std::string packageVersion = version();
-    CHECK(packageVersion[0] == '@');
-
     if (!cpp_compatible) {
-        components->push_back(packageVersion.substr(1));
+        components->push_back(getPackageMajorVersion() +
+                "." + getPackageMinorVersion());
         return;
     }
 
-    const size_t dotPos = packageVersion.find('.');
-
     // Form "Vmajor_minor".
     std::string versionString = "V";
-    versionString.append(packageVersion.substr(1, dotPos - 1));
+    versionString.append(getPackageMajorVersion());
     versionString.append("_");
-    versionString.append(packageVersion.substr(dotPos + 1));
+    versionString.append(getPackageMinorVersion());
 
     components->push_back(versionString);
 }
 
+std::string FQName::getPackageMajorVersion() const {
+    const std::string packageVersion = version();
+    CHECK(packageVersion[0] == '@');
+    const size_t dotPos = packageVersion.find('.');
+    CHECK(dotPos != std::string::npos);
+    return packageVersion.substr(1, dotPos - 1);
+}
+
+std::string FQName::getPackageMinorVersion() const {
+    const std::string packageVersion = version();
+    CHECK(packageVersion[0] == '@');
+    const size_t dotPos = packageVersion.find('.');
+    CHECK(dotPos != std::string::npos);
+    return packageVersion.substr(dotPos + 1);
+}
+
 bool FQName::endsWith(const FQName &other) const {
     std::string s1 = string();
     std::string s2 = other.string();
diff --git a/FQName.h b/FQName.h
index a4a8565..b893bd7 100644
--- a/FQName.h
+++ b/FQName.h
@@ -116,6 +116,9 @@
             std::vector<std::string> *components,
             bool cpp_compatible) const;
 
+    std::string getPackageMajorVersion() const;
+
+    std::string getPackageMinorVersion() const;
 private:
     bool mValid;
     std::string mPackage;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 2ad8019..84001cf 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -189,7 +189,14 @@
     if (isInterface) {
         const Interface *iface = mRootScope->getInterface();
         const Interface *superType = iface->superType();
-
+        out << "constexpr static hidl_version version = {"
+            << mPackage.getPackageMajorVersion() << ","
+            << mPackage.getPackageMinorVersion() << "};\n";
+        out << "virtual const hidl_version& getInterfaceVersion() const {\n";
+        out.indent();
+        out << "return version;\n";
+        out.unindent();
+        out << "}\n\n";
         out << "virtual bool isRemote() const { return false; }\n\n";
         bool haveCallbacks = false;
         for (const auto &method : iface->methods()) {
@@ -743,6 +750,7 @@
     status_t err = generateTypeSource(out, ifaceName);
 
     if (err == OK && isInterface) {
+        out << "constexpr hidl_version " << ifaceName << "::version;\n\n";
         err = generateProxySource(out, baseName);
     }
 
diff --git a/test/java_test/hidl_test_java_native.cpp b/test/java_test/hidl_test_java_native.cpp
index c11b28e..3935bff 100644
--- a/test/java_test/hidl_test_java_native.cpp
+++ b/test/java_test/hidl_test_java_native.cpp
@@ -342,9 +342,7 @@
     void SetUp() override {
         using namespace ::android::hardware;
 
-        const hidl_version kVersion = make_hidl_version(1, 0);
-
-        baz = IBaz::getService("baz", kVersion);
+        baz = IBaz::getService("baz");
 
         CHECK(baz != NULL);
     }
@@ -587,9 +585,7 @@
     } else {
         sp<Baz> baz = new Baz;
 
-        const hidl_version kVersion = make_hidl_version(1, 0);
-
-        baz->registerAsService("baz", kVersion);
+        baz->registerAsService("baz");
 
         ProcessState::self()->startThreadPool();
         ProcessState::self()->setThreadPoolMaxThreadCount(0);
diff --git a/test/main.cpp b/test/main.cpp
index 2a55b8e..17170af 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -384,12 +384,12 @@
 
 
 template <class T>
-static void startServer(T server, const android::hardware::hidl_version kVersion,
+static void startServer(T server,
                         const char *serviceName,
                         const char *tag) {
     using namespace android::hardware;
     ALOGI("SERVER(%s) registering", tag);
-    server->registerAsService(serviceName, kVersion);
+    server->registerAsService(serviceName);
     ALOGI("SERVER(%s) starting", tag);
     ProcessState::self()->setThreadPoolMaxThreadCount(0);
     ProcessState::self()->startThreadPool();
@@ -408,15 +408,13 @@
     virtual void SetUp() override {
         ALOGI("Test setup beginning...");
         using namespace android::hardware;
-        const hidl_version kVersion = make_hidl_version(1, 0);
-
-        foo = IFoo::getService("foo", kVersion);
+        foo = IFoo::getService("foo");
         CHECK(foo != NULL);
 
-        bar = IBar::getService("foo", kVersion);
+        bar = IBar::getService("foo");
         CHECK(bar != NULL);
 
-        fooCb = IFooCallback::getService("foo callback", kVersion);
+        fooCb = IFooCallback::getService("foo callback");
         CHECK(fooCb != NULL);
 
         ALOGI("Test setup complete");
@@ -434,15 +432,13 @@
         // use fork to create and kill to destroy server processes.
         if ((barServerPid = fork()) == 0) {
             // Fear me, I am a child.
-            startServer(new Bar, android::hardware::make_hidl_version(1, 0),
-                "foo", "Bar"); // never returns
+            startServer(new Bar, "foo", "Bar"); // never returns
             return;
         }
 
         if ((fooCallbackServerPid = fork()) == 0) {
             // Fear me, I am a second child.
-            startServer(new FooCallback, android::hardware::make_hidl_version(1, 0),
-                "foo callback", "FooCalback"); // never returns
+            startServer(new FooCallback, "foo callback", "FooCalback"); // never returns
             return;
         }