Remove toBinder from IHidlInterfaceBase.

Bug: 32001926
Test: hidl_test

Bug: 32559427 (4) added FQName::getTopLevelHwName

Change-Id: Ibde4f76ee51b729722569d420262182ea750b05b
diff --git a/Interface.cpp b/Interface.cpp
index 78dc679..f148386 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -187,6 +187,23 @@
     return fqName().getInterfaceBaseName();
 }
 
+FQName Interface::getHwName() const {
+    return FQName(fqName().package(), fqName().version(), "IHw" + getBaseName());
+}
+
+FQName Interface::getPassthroughName() const {
+    return FQName(fqName().package(), fqName().version(), "Bp" + getBaseName());
+}
+
+FQName Interface::getNativeName() const {
+    return FQName(fqName().package(), fqName().version(), "Bn" + getBaseName());
+}
+
+FQName Interface::getSameprocessName() const {
+    return FQName(fqName().package(), fqName().version(), "Bs" + getBaseName());
+}
+
+
 std::string Interface::getCppType(StorageMode mode,
                                   bool specifyNamespaces) const {
     const std::string base =
@@ -256,11 +273,31 @@
         out.unindent();
         out << "} else {\n";
         out.indent();
-        out << "_hidl_err = "
-            << parcelObjDeref
-            << "writeStrongBinder("
-            << name
-            << "->toBinder());\n";
+        out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
+            << "::android::hardware::toBinder<\n";
+        out.indentBlock(2, [&] {
+            out << fqName().cppNamespace()
+                << "::I"
+                << getBaseName()
+                << ", "
+                << fqName().cppNamespace()
+                << "::IHw"
+                << getBaseName()
+                << ">("
+                << name
+                << ");\n";
+        });
+        out << "if (_hidl_binder.get() != nullptr) {\n";
+        out.indentBlock([&] {
+            out << "_hidl_err = "
+                << parcelObjDeref
+                << "writeStrongBinder(_hidl_binder);\n";
+        });
+        out << "} else {\n";
+        out.indentBlock([&] {
+            out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
+        });
+        out << "}\n";
         out.unindent();
         out << "}\n";
 
diff --git a/Interface.h b/Interface.h
index 61981cc..1ab14c5 100644
--- a/Interface.h
+++ b/Interface.h
@@ -63,6 +63,11 @@
 
     std::string getBaseName() const;
 
+    FQName getHwName() const;
+    FQName getPassthroughName() const;
+    FQName getNativeName() const;
+    FQName getSameprocessName() const;
+
     std::string getCppType(
             StorageMode mode,
             bool specifyNamespaces) const override;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 09bc657..6b162ff 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -215,8 +215,6 @@
         out.unindent();
         out << "}\n\n";
         out << "virtual bool isRemote() const override { return false; }\n\n";
-        out << "virtual ::android::sp<::android::hardware::IBinder> "
-            << "toBinder() override;\n\n";
         bool haveCallbacks = false;
         for (const auto &method : iface->methods()) {
             const bool returnsValue = !method->results().empty();
@@ -298,7 +296,9 @@
 
         out << "\nstatic const ::android::String16 descriptor;\n\n";
 
-        out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
+        out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n\n";
+
+        out << "private: static int hidlStaticBlock;\n";
     }
 
     if (isInterface) {
@@ -772,6 +772,28 @@
             << iface->fqName().string()
             << "\");\n\n";
 
+        out << "int I"
+            << iface->getBaseName()
+            << "::hidlStaticBlock = []() -> int {\n";
+        out.indentBlock([&] {
+            out << "::android::hardware::gBnConstructorMap[::android::String16::std_string(I"
+                << iface->getBaseName()
+                << "::descriptor)]\n";
+            out.indentBlock(2, [&] {
+                out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
+                out.indentBlock([&] {
+                    out << "return new Bn"
+                        << iface->getBaseName()
+                        << "(reinterpret_cast<I"
+                        << iface->getBaseName()
+                        << " *>(iIntf));\n";
+                });
+                out << "};\n";
+            });
+            out << "return 1;\n";
+        });
+        out << "}();\n\n";
+
         err = generateInterfaceSource(out);
     }
 
@@ -1529,27 +1551,6 @@
 status_t AST::generateInterfaceSource(Formatter &out) const {
     const Interface *iface = mRootScope->getInterface();
 
-
-    // generate toBinder functions
-    out << "::android::sp<::android::hardware::IBinder> I"
-        << iface->getBaseName()
-        << "::toBinder() {\n";
-    out.indent();
-    out << "if (isRemote()) {\n";
-    out.indent();
-    out << "return ::android::hardware::IInterface::asBinder("
-        << "static_cast<IHw"
-        << iface->getBaseName()
-        << " *>(this));\n";
-    out.unindent();
-    out << "} else {\n";
-    out.indent();
-    out << "return new Bn" << iface->getBaseName() << "(this);\n";
-    out.unindent();
-    out << "}\n";
-    out.unindent();
-    out << "}\n\n";
-
     // generate castFrom functions
     if (!iface->isRootType()) {
         std::string childTypeResult = iface->getCppResultType();
@@ -1566,7 +1567,8 @@
             out << "return ::android::hardware::castInterface<";
             out << "I" << iface->getBaseName() << ", "
                 << superType->fqName().cppName() << ", "
-                << "Bp" << iface->getBaseName()
+                << "Bp" << iface->getBaseName() << ", "
+                << superType->getHwName().cppName()
                 << ">(\n";
             out.indent();
             out.indent();