Merge "Remove unnecessary dependencies." am: aea9f83e6d am: 173aa15ec9
am: e06b744b3d
Change-Id: I3f56aba6ea41ca4a1a3098184c64f07e1a86a081
diff --git a/transport/Android.bp b/transport/Android.bp
index c7bb63b..73eee3a 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -35,6 +35,7 @@
"libhidlbase",
"libhwbinder",
"libcutils",
+ "libvndksupport",
],
export_shared_lib_headers: [
"libbase",
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index b14479e..a8ae75c 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -36,6 +36,7 @@
#include <android-base/properties.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/Parcel.h>
+#include <vndksupport/linker.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android/hidl/manager/1.0/BpHwServiceManager.h>
@@ -45,10 +46,6 @@
#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so");
-extern "C" {
- android_namespace_t* android_get_exported_namespace(const char*);
-}
-
using android::base::WaitForProperty;
using android::hidl::manager::V1_0::IServiceManager;
@@ -253,32 +250,27 @@
}
struct PassthroughServiceManager : IServiceManager {
- Return<sp<IBase>> get(const hidl_string& fqName,
- const hidl_string& name) override {
- std::string stdFqName(fqName.c_str());
-
+ static void openLibs(const std::string& fqName,
+ std::function<bool /* continue */(void* /* handle */,
+ const std::string& /* lib */, const std::string& /* sym */)> eachLib) {
//fqName looks like android.hardware.foo@1.0::IFoo
- size_t idx = stdFqName.find("::");
+ size_t idx = fqName.find("::");
if (idx == std::string::npos ||
- idx + strlen("::") + 1 >= stdFqName.size()) {
+ idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
- return nullptr;
+ return;
}
- std::string packageAndVersion = stdFqName.substr(0, idx);
- std::string ifaceName = stdFqName.substr(idx + strlen("::"));
+ std::string packageAndVersion = fqName.substr(0, idx);
+ std::string ifaceName = fqName.substr(idx + strlen("::"));
const std::string prefix = packageAndVersion + "-impl";
const std::string sym = "HIDL_FETCH_" + ifaceName;
- const android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
const int dlMode = RTLD_LAZY;
void *handle = nullptr;
- // TODO: lookup in VINTF instead
- // TODO(b/34135607): Remove HAL_LIBRARY_PATH_SYSTEM
-
dlerror(); // clear
for (const std::string &path : {
@@ -289,26 +281,9 @@
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
- // If sphal namespace is available, try to load from the
- // namespace first. If it fails, fall back to the original
- // dlopen, which loads from the current namespace.
- if (sphal_namespace != nullptr && path != HAL_LIBRARY_PATH_SYSTEM) {
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- // const_cast is dirty but required because
- // library_namespace field is non-const.
- .library_namespace = const_cast<android_namespace_t*>(sphal_namespace),
- };
- handle = android_dlopen_ext(fullPath.c_str(), dlMode, &dlextinfo);
- if (handle == nullptr) {
- const char* error = dlerror();
- LOG(WARNING) << "Failed to dlopen " << lib << " from sphal namespace:"
- << (error == nullptr ? "unknown error" : error);
- } else {
- LOG(DEBUG) << lib << " loaded from sphal namespace.";
- }
- }
- if (handle == nullptr) {
+ if (path != HAL_LIBRARY_PATH_SYSTEM) {
+ handle = android_load_sphal_library(fullPath.c_str(), dlMode);
+ } else {
handle = dlopen(fullPath.c_str(), dlMode);
}
@@ -319,31 +294,41 @@
continue;
}
- IBase* (*generator)(const char* name);
- *(void **)(&generator) = dlsym(handle, sym.c_str());
- if(!generator) {
- const char* error = dlerror();
- LOG(ERROR) << "Passthrough lookup opened " << lib
- << " but could not find symbol " << sym << ": "
- << (error == nullptr ? "unknown error" : error);
- dlclose(handle);
- continue;
+ if (!eachLib(handle, lib, sym)) {
+ return;
}
-
- IBase *interface = (*generator)(name.c_str());
-
- if (interface == nullptr) {
- dlclose(handle);
- continue; // this module doesn't provide this instance name
- }
-
- registerReference(fqName, name);
-
- return interface;
}
}
+ }
- return nullptr;
+ Return<sp<IBase>> get(const hidl_string& fqName,
+ const hidl_string& name) override {
+ sp<IBase> ret = nullptr;
+
+ openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
+ IBase* (*generator)(const char* name);
+ *(void **)(&generator) = dlsym(handle, sym.c_str());
+ if(!generator) {
+ const char* error = dlerror();
+ LOG(ERROR) << "Passthrough lookup opened " << lib
+ << " but could not find symbol " << sym << ": "
+ << (error == nullptr ? "unknown error" : error);
+ dlclose(handle);
+ return true;
+ }
+
+ ret = (*generator)(name.c_str());
+
+ if (ret == nullptr) {
+ dlclose(handle);
+ return true; // this module doesn't provide this instance name
+ }
+
+ registerReference(fqName, name);
+ return false;
+ });
+
+ return ret;
}
Return<bool> add(const hidl_string& /* name */,
@@ -434,6 +419,14 @@
namespace details {
+void preloadPassthroughService(const std::string &descriptor) {
+ PassthroughServiceManager::openLibs(descriptor,
+ [&](void* /* handle */, const std::string& /* lib */, const std::string& /* sym */) {
+ // do nothing
+ return true; // open all libs
+ });
+}
+
struct Waiter : IServiceNotification {
Return<void> onRegistration(const hidl_string& /* fqName */,
const hidl_string& /* name */,
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
index 2b2266b..324a584 100644
--- a/transport/include/hidl/ServiceManagement.h
+++ b/transport/include/hidl/ServiceManagement.h
@@ -32,12 +32,6 @@
namespace hardware {
-// These functions are for internal use by hidl. If you want to get ahold
-// of an interface, the best way to do this is by calling IFoo::getService()
-
-sp<::android::hidl::manager::V1_0::IServiceManager> defaultServiceManager();
-sp<::android::hidl::manager::V1_0::IServiceManager> getPassthroughServiceManager();
-
namespace details {
// e.x.: android.hardware.foo@1.0, IFoo, default
void onRegistration(const std::string &packageName,
@@ -46,8 +40,26 @@
// e.x.: android.hardware.foo@1.0::IFoo, default
void waitForHwService(const std::string &interface, const std::string &instanceName);
+
+void preloadPassthroughService(const std::string &descriptor);
};
+// These functions are for internal use by hidl. If you want to get ahold
+// of an interface, the best way to do this is by calling IFoo::getService()
+sp<::android::hidl::manager::V1_0::IServiceManager> defaultServiceManager();
+sp<::android::hidl::manager::V1_0::IServiceManager> getPassthroughServiceManager();
+
+/**
+ * Given a service that is in passthrough mode, this function will go ahead and load the
+ * required passthrough module library (but not call HIDL_FETCH_I* functions to instantiate it).
+ *
+ * E.x.: preloadPassthroughService<IFoo>();
+ */
+template<typename I>
+static inline void preloadPassthroughService() {
+ details::preloadPassthroughService(I::descriptor);
+}
+
}; // namespace hardware
}; // namespace android
diff --git a/transport/token/1.0/utils/Android.bp b/transport/token/1.0/utils/Android.bp
index 0360d99..ab77a2a 100644
--- a/transport/token/1.0/utils/Android.bp
+++ b/transport/token/1.0/utils/Android.bp
@@ -14,6 +14,7 @@
cc_library {
name: "android.hidl.token@1.0-utils",
+ vendor_available: true,
srcs: [
"HybridInterface.cpp",