Revert "Revert "Allow proxies to be compared.""
This reverts commit 7c238ef97977204a5a5ff65a39f602ceb44ed307.
(originally reverted due to merge conflicts)
Bug: 32172906
Test: hidl_test
Change-Id: I590c60ed529847742dede590e1e9a152a7650da0
diff --git a/transport/Static.cpp b/transport/Static.cpp
index 18cb475..784b835 100644
--- a/transport/Static.cpp
+++ b/transport/Static.cpp
@@ -32,6 +32,9 @@
ConcurrentMap<std::string, std::function<sp<IBinder>(void *)>>
gBnConstructorMap{};
+ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
+ gBnMap{};
+
ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap{};
ConcurrentMap<std::string, std::function<sp<::android::hidl::base::V1_0::IBase>(void *)>>
diff --git a/transport/include/hidl/ConcurrentMap.h b/transport/include/hidl/ConcurrentMap.h
index 18881f1..cd55ad4 100644
--- a/transport/include/hidl/ConcurrentMap.h
+++ b/transport/include/hidl/ConcurrentMap.h
@@ -50,7 +50,19 @@
return mMap.erase(k);
}
-private:
+ std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(mMutex); }
+
+ void setLocked(K&& k, V&& v) { mMap[std::forward<K>(k)] = std::forward<V>(v); }
+
+ const V& getLocked(const K& k, const V& def) const {
+ const_iterator iter = mMap.find(k);
+ if (iter == mMap.end()) {
+ return def;
+ }
+ return iter->second;
+ }
+
+ private:
mutable std::mutex mMutex;
std::map<K, V> mMap;
};
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index 6f82dbc..47ff581 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -306,25 +306,42 @@
// 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 ProxyType>
+template <typename IType>
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<ProxyType *>(ifacePtr));
+ return ::android::hardware::IInterface::asBinder(
+ static_cast<BpInterface<IType>*>(ifacePtr));
} else {
std::string myDescriptor = details::getDescriptor(ifacePtr);
if (myDescriptor.empty()) {
// interfaceDescriptor fails
return nullptr;
}
- auto func = details::gBnConstructorMap.get(myDescriptor, nullptr);
- if (!func) {
- return nullptr;
+
+ // for get + set
+ std::unique_lock<std::mutex> _lock = details::gBnMap.lock();
+
+ wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr);
+ sp<IBinder> sBnObj = wBnObj.promote();
+
+ if (sBnObj == nullptr) {
+ auto func = details::gBnConstructorMap.get(myDescriptor, nullptr);
+ if (!func) {
+ return nullptr;
+ }
+
+ sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));
+
+ if (sBnObj != nullptr) {
+ details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
+ }
}
- return sp<IBinder>(func(static_cast<void *>(ifacePtr)));
+
+ return sBnObj;
}
}
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
index 0c174f7..d116598 100644
--- a/transport/include/hidl/HidlTransportSupport.h
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -62,6 +62,15 @@
bool setMinSchedulerPolicy(const sp<::android::hidl::base::V1_0::IBase>& service,
int policy, int priority);
+template <typename ILeft, typename IRight>
+bool interfacesEqual(sp<ILeft> left, sp<IRight> right) {
+ if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
+ return left == right;
+ }
+
+ return toBinder<ILeft>(left) == toBinder<IRight>(right);
+}
+
namespace details {
// cast the interface IParent to IChild.
@@ -72,8 +81,8 @@
// 3. !emitError, calling into parent fails.
// Return an error Return object if:
// 1. emitError, calling into parent fails.
-template<typename IChild, typename IParent, typename BpChild, typename BpParent>
-Return<sp<IChild>> castInterface(sp<IParent> parent, const char *childIndicator, bool emitError) {
+template <typename IChild, typename IParent, typename BpChild>
+Return<sp<IChild>> castInterface(sp<IParent> parent, const char* childIndicator, bool emitError) {
if (parent.get() == nullptr) {
// casts always succeed with nullptrs.
return nullptr;
@@ -92,7 +101,7 @@
// TODO b/32001926 Needs to be fixed for socket mode.
if (parent->isRemote()) {
// binderized mode. Got BpChild. grab the remote and wrap it.
- return sp<IChild>(new BpChild(toBinder<IParent, BpParent>(parent)));
+ return sp<IChild>(new BpChild(toBinder<IParent>(parent)));
}
// Passthrough mode. Got BnChild and BsChild.
return sp<IChild>(static_cast<IChild *>(parent.get()));
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index 0133ff7..63b06fe 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -22,6 +22,7 @@
#include <android/hidl/base/1.0/IBase.h>
#include <hidl/ConcurrentMap.h>
#include <hwbinder/IBinder.h>
+#include <hwbinder/IInterface.h>
#include <utils/StrongPointer.h>
namespace android {
@@ -33,14 +34,18 @@
int prio;
};
+extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap;
+
+// For HidlBinderSupport and autogenerated code
+extern ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
+ gBnMap;
+
// For HidlBinderSupport and autogenerated code
// value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
// returns sp<IBinder>
extern ConcurrentMap<std::string,
std::function<sp<IBinder>(void *)>> gBnConstructorMap;
-extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap;
-
// For HidlPassthroughSupport and autogenerated code
// value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
// returns sp<IBase>