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",