toBinder: always safe.

Previously this method required the right type to pass in for proxies
or it would lead to UB behavior. Now, the right field has been exposed,
so it can be called on anything safely.

Bug: 66921961
Test: hidl_test
Test: boot and check for crashes
Change-Id: Ib1b143d8a0189156453c723ee6675be3e90b0486
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index a2ca5fa..a96050c 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -19,6 +19,7 @@
 #include <hidl/HidlBinderSupport.h>
 
 #include <InternalStatic.h>  // TODO(b/69122224): remove this include, for getOrCreateCachedBinder
+#include <android/hidl/base/1.0/BpHwBase.h>
 #include <hwbinder/IPCThreadState.h>
 
 // C includes
@@ -227,8 +228,17 @@
 }
 
 sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) {
-    LOG_ALWAYS_FATAL_IF(ifacePtr->isRemote(), "%s does not have a way to construct remote binders",
-                        __func__);
+    if (ifacePtr == nullptr) {
+        return nullptr;
+    }
+
+    if (ifacePtr->isRemote()) {
+        using ::android::hidl::base::V1_0::BpHwBase;
+
+        BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr);
+        BpHwRefBase* bpRefBase = static_cast<BpHwRefBase*>(bpBase);
+        return sp<IBinder>(bpRefBase->remote());
+    }
 
     std::string descriptor = details::getDescriptor(ifacePtr);
     if (descriptor.empty()) {
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index 8fe1450..a098805 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -309,7 +309,7 @@
 // ---------------------- support for casting interfaces
 
 // Constructs a binder for this interface and caches it. If it has already been created
-// then it returns it. ifacePtr must be a local object.
+// then it returns it.
 sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr);
 
 // Construct a smallest possible binder from the given interface.
@@ -321,15 +321,7 @@
           typename = std::enable_if_t<std::is_same<details::i_tag, typename IType::_hidl_tag>::value>>
 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<BpInterface<IType>*>(ifacePtr));
-    } else {
-        return getOrCreateCachedBinder(ifacePtr);
-    }
+    return getOrCreateCachedBinder(ifacePtr);
 }
 
 template <typename IType, typename ProxyType, typename StubType>