Merge "Introduce fromBinder() helper."
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 102fa6c..6753cb8 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "ServiceManagement"
+#include <hidl/HidlBinderSupport.h>
#include <hidl/ServiceManagement.h>
#include <hidl/Static.h>
#include <hidl/Status.h>
@@ -28,10 +29,12 @@
#include <unistd.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <android/hidl/manager/1.0/IHwServiceManager.h>
+#include <android/hidl/manager/1.0/BpServiceManager.h>
+#include <android/hidl/manager/1.0/BnServiceManager.h>
-using android::hidl::manager::V1_0::IHwServiceManager;
using android::hidl::manager::V1_0::IServiceManager;
+using android::hidl::manager::V1_0::BpServiceManager;
+using android::hidl::manager::V1_0::BnServiceManager;
namespace android {
namespace hardware {
@@ -47,7 +50,7 @@
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
- gDefaultServiceManager = interface_cast<IHwServiceManager>(
+ gDefaultServiceManager = fromBinder<IServiceManager, BpServiceManager, BnServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
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(); \
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
index 1d22cb7..190227f 100644
--- a/transport/include/hidl/HidlTransportSupport.h
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -19,27 +19,20 @@
#include <hidl/HidlBinderSupport.h>
#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportUtils.h>
namespace android {
namespace hardware {
// cast the interface IParent to IChild.
// Return nullptr if parent is null or any failure.
-template<typename IChild, typename IParent, typename BpChild, typename IHwParent>
+template<typename IChild, typename IParent, typename BpChild, typename BpParent>
sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
if (parent.get() == nullptr) {
// casts always succeed with nullptrs.
return nullptr;
}
- bool canCast = false;
- parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
- for (size_t i = 0; i < allowedCastTypes.size(); i++) {
- if (allowedCastTypes[i] == childIndicator) {
- canCast = true;
- break;
- }
- }
- });
+ bool canCast = canCastInterface(parent.get(), childIndicator);
if (!canCast) {
return sp<IChild>(nullptr); // cast failed.
@@ -47,7 +40,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, IHwParent>(parent)));
+ return sp<IChild>(new BpChild(toBinder<IParent, BpParent>(parent)));
}
// Passthrough mode. Got BnChild and BsChild.
return sp<IChild>(static_cast<IChild *>(parent.get()));
diff --git a/transport/include/hidl/HidlTransportUtils.h b/transport/include/hidl/HidlTransportUtils.h
new file mode 100644
index 0000000..d890988
--- /dev/null
+++ b/transport/include/hidl/HidlTransportUtils.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HIDL_TRANSPORT_UTILS_H
+#define ANDROID_HIDL_TRANSPORT_UTILS_H
+
+#include <android/hidl/base/1.0/IBase.h>
+
+namespace android {
+namespace hardware {
+
+/*
+ * Verifies the interface chain of 'interface' contains 'castTo'
+ */
+inline bool canCastInterface(::android::hidl::base::V1_0::IBase* interface, const char* castTo) {
+ if (interface == nullptr) {
+ return false;
+ }
+
+ bool canCast = false;
+ interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
+ for (size_t i = 0; i < types.size(); i++) {
+ if (types[i] == castTo) {
+ canCast = true;
+ break;
+ }
+ }
+ });
+ return canCast;
+}
+
+} // namespace hardware
+} // namespace android
+
+#endif //ANDROID_HIDL_TRANSPORT_UTILS_H