toBinder: always safe. am: 986fa094d3
am: 45342c0395

Change-Id: I1aae678dd9fbd073d7b7cce266e7ad4e0174d112
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index c9b2693..b9d2d19 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
@@ -237,8 +238,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>