Introduce fromBinder() helper.

To safely cast binder objects back to HIDL interfaces.

Modified toBinder(), to take into account IHw
classes no longer exist.

Removed an obsolete conversion of IFoo to BnFoo
in the servicemanager add macro - BnFoo is transport
specific and does not belong there.

Test: mma, hidl_test, hidl_test_java
Bug: 33173166
Change-Id: Iae84c900584a008c9cc8e03d1914e95d0fae77ce
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index a596917..8c2cd61 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -18,11 +18,12 @@
 #define ANDROID_HIDL_BINDER_SUPPORT_H
 
 #include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportUtils.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Static.h>
 #include <hwbinder/IBinder.h>
 #include <hwbinder/Parcel.h>
-
+#include <android/hidl/base/1.0/BnBase.h>
 // Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor,
 // etc. to interact with Parcel.
 
@@ -286,14 +287,14 @@
 // Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
 // and iface is of class IChild. BnChild will be used to wrapped the given iface.
 // Return nullptr if iface is null or any failure.
-template <typename IType, typename IHwType>
+template <typename IType, typename ProxyType>
 sp<IBinder> toBinder(sp<IType> iface) {
     IType *ifacePtr = iface.get();
     if (ifacePtr == nullptr) {
         return nullptr;
     }
     if (ifacePtr->isRemote()) {
-        return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr));
+        return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr));
     } else {
         std::string myDescriptor{};
         ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
@@ -313,6 +314,26 @@
     }
 }
 
+template <typename IType, typename ProxyType, typename StubType>
+sp<IType> fromBinder(const sp<IBinder>& binderIface) {
+    using ::android::hidl::base::V1_0::IBase;
+    using ::android::hidl::base::V1_0::BnBase;
+
+    if (binderIface.get() == nullptr) {
+        return nullptr;
+    }
+    if (binderIface->localBinder() == nullptr) {
+        return new ProxyType(binderIface);
+    }
+    sp<IBase> base = static_cast<BnBase*>(binderIface.get())->getImpl();
+    if (canCastInterface(base.get(), IType::descriptor)) {
+        StubType* stub = static_cast<StubType*>(binderIface.get());
+        return stub->getImpl();
+    } else {
+        return nullptr;
+    }
+}
+
 #define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE)                       \
     ::android::sp<I##INTERFACE> I##INTERFACE::getService(                                \
             const std::string &serviceName, bool getStub)                                \
@@ -363,14 +384,13 @@
         using ::android::sp;                                                             \
         using ::android::hardware::defaultServiceManager;                                \
         using ::android::hidl::manager::V1_0::IServiceManager;                           \
-        sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this);                         \
         const sp<IServiceManager> sm = defaultServiceManager();                          \
         bool success = false;                                                            \
         ::android::hardware::Return<void> ret =                                          \
             this->interfaceChain(                                                        \
-                [&success, &sm, &serviceName, &binderIface](const auto &chain) {         \
+                [&success, &sm, &serviceName, this](const auto &chain) {                 \
                     ::android::hardware::Return<bool> addRet =                           \
-                            sm->add(chain, serviceName.c_str(), binderIface);            \
+                            sm->add(chain, serviceName.c_str(), this);                   \
                     success = addRet.isOk() && addRet;                                   \
                 });                                                                      \
         success = success && ret.getStatus().isOk();                                     \