Merge "Add missing freeHandle to setTo"
diff --git a/base/HidlInternal.cpp b/base/HidlInternal.cpp
index 45afda3..9c0efbb 100644
--- a/base/HidlInternal.cpp
+++ b/base/HidlInternal.cpp
@@ -19,6 +19,14 @@
 #include <hidl/HidlInternal.h>
 
 #include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
+#include <dirent.h>
+#include <dlfcn.h>
+#include <hidl-util/FQName.h>
+#include <regex>
+#endif
 
 namespace android {
 namespace hardware {
@@ -28,6 +36,113 @@
     LOG(FATAL) << message;
 }
 
+// ----------------------------------------------------------------------
+// HidlInstrumentor implementation.
+HidlInstrumentor::HidlInstrumentor(
+        const std::string &package,
+        const std::string &interface)
+        : mInstrumentationLibPackage(package), mInterfaceName(interface) {
+    configureInstrumentation(false);
+}
+
+HidlInstrumentor:: ~HidlInstrumentor() {}
+
+void HidlInstrumentor::configureInstrumentation(bool log) {
+    bool enable_instrumentation = property_get_bool(
+            "hal.instrumentation.enable",
+            false);
+    if (enable_instrumentation != mEnableInstrumentation) {
+        mEnableInstrumentation = enable_instrumentation;
+        if (mEnableInstrumentation) {
+            if (log) {
+                LOG(INFO) << "Enable instrumentation.";
+            }
+            registerInstrumentationCallbacks (&mInstrumentationCallbacks);
+        } else {
+            if (log) {
+                LOG(INFO) << "Disable instrumentation.";
+            }
+            mInstrumentationCallbacks.clear();
+        }
+    }
+}
+
+void HidlInstrumentor::registerInstrumentationCallbacks(
+        std::vector<InstrumentationCallback> *instrumentationCallbacks) {
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
+    std::vector<std::string> instrumentationLibPaths;
+    char instrumentation_lib_path[PROPERTY_VALUE_MAX];
+    if (property_get("hal.instrumentation.lib.path",
+                     instrumentation_lib_path,
+                     "") > 0) {
+        instrumentationLibPaths.push_back(instrumentation_lib_path);
+    } else {
+        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
+        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
+        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
+    }
+
+    for (auto path : instrumentationLibPaths) {
+        DIR *dir = opendir(path.c_str());
+        if (dir == 0) {
+            LOG(WARNING) << path << " does not exist. ";
+            return;
+        }
+
+        struct dirent *file;
+        while ((file = readdir(dir)) != NULL) {
+            if (!isInstrumentationLib(file))
+                continue;
+
+            void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
+            char *error;
+            if (handle == nullptr) {
+                LOG(WARNING) << "couldn't load file: " << file->d_name
+                    << " error: " << dlerror();
+                continue;
+            }
+
+            dlerror(); /* Clear any existing error */
+
+            using cb_fun = void (*)(
+                    const InstrumentationEvent,
+                    const char *,
+                    const char *,
+                    const char *,
+                    const char *,
+                    std::vector<void *> *);
+            FQName package_name = FQName(mInstrumentationLibPackage);
+            auto cb = (cb_fun)dlsym(handle, ("HIDL_INSTRUMENTATION_FUNCTION_"
+                        + package_name.tokenName() + "_"
+                        + mInterfaceName).c_str());
+            if ((error = dlerror()) != NULL) {
+                LOG(WARNING)
+                    << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION_"
+                    << mInterfaceName << ", error: " << error;
+                continue;
+            }
+            instrumentationCallbacks->push_back(cb);
+            LOG(INFO) << "Register instrumentation callback from "
+                << file->d_name;
+        }
+        closedir(dir);
+    }
+#else
+    // No-op for user builds.
+    return;
+#endif
+}
+
+bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
+    if (file->d_type != DT_REG) return false;
+    std::cmatch cm;
+    std::regex e("^" + mInstrumentationLibPackage + "(.*).profiler.so$");
+    if (std::regex_match(file->d_name, cm, e)) return true;
+#endif
+    return false;
+}
+
 }  // namespace details
 }  // namespace hardware
 }  // namespace android
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index 7320f3f..dd93534 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -25,13 +25,6 @@
 #include <vintf/VendorManifest.h>
 #include <vintf/parse_string.h>
 
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
-#include <cutils/properties.h>
-#include <dlfcn.h>
-#include <regex>
-#include <utility>
-#endif
-
 namespace android {
 namespace hardware {
 vintf::Transport getTransportForFrameworkPackages(const std::string &name) {
@@ -61,15 +54,13 @@
         LOG(WARNING) << "getTransportFromManifest: Cannot find vendor interface manifest.";
         return vintf::Transport::EMPTY;
     }
-    size_t majorVer;
-    size_t minorVer;
-    if (   !::android::base::ParseUint(fqName.getPackageMajorVersion(), &majorVer)
-        || !::android::base::ParseUint(fqName.getPackageMinorVersion(), &minorVer)) {
+    if (!fqName.hasVersion()) {
         LOG(ERROR) << "getTransportFromManifest: " << fqName.string()
                    << " does not specify a version.";
         return vintf::Transport::EMPTY;
     }
-    vintf::Transport tr = vm->getTransport(package, vintf::Version{majorVer, minorVer});
+    vintf::Transport tr = vm->getTransport(package,
+            vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()});
     if (tr == vintf::Transport::EMPTY) {
         LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
                      << package << fqName.atVersion() << " in vendor interface manifest.";
@@ -253,10 +244,6 @@
     return *this;
 }
 
-bool hidl_string::operator< (const hidl_string &rhs) const {
-    return strcmp(mBuffer, rhs.mBuffer) < 0;
-}
-
 hidl_string::operator std::string() const {
     return std::string(mBuffer, mSize);
 }
@@ -323,113 +310,6 @@
     return mSize == 0;
 }
 
-// ----------------------------------------------------------------------
-// HidlInstrumentor implementation.
-HidlInstrumentor::HidlInstrumentor(
-        const std::string &package,
-        const std::string &interface)
-        : mInstrumentationLibPackage(package), mInterfaceName(interface) {
-    configureInstrumentation(false);
-}
-
-HidlInstrumentor:: ~HidlInstrumentor() {}
-
-void HidlInstrumentor::configureInstrumentation(bool log) {
-    bool enable_instrumentation = property_get_bool(
-            "hal.instrumentation.enable",
-            false);
-    if (enable_instrumentation != mEnableInstrumentation) {
-        mEnableInstrumentation = enable_instrumentation;
-        if (mEnableInstrumentation) {
-            if (log) {
-                LOG(INFO) << "Enable instrumentation.";
-            }
-            registerInstrumentationCallbacks (&mInstrumentationCallbacks);
-        } else {
-            if (log) {
-                LOG(INFO) << "Disable instrumentation.";
-            }
-            mInstrumentationCallbacks.clear();
-        }
-    }
-}
-
-void HidlInstrumentor::registerInstrumentationCallbacks(
-        std::vector<InstrumentationCallback> *instrumentationCallbacks) {
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
-    std::vector<std::string> instrumentationLibPaths;
-    char instrumentation_lib_path[PROPERTY_VALUE_MAX];
-    if (property_get("hal.instrumentation.lib.path",
-                     instrumentation_lib_path,
-                     "") > 0) {
-        instrumentationLibPaths.push_back(instrumentation_lib_path);
-    } else {
-        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
-        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
-        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
-    }
-
-    for (auto path : instrumentationLibPaths) {
-        DIR *dir = opendir(path.c_str());
-        if (dir == 0) {
-            LOG(WARNING) << path << " does not exist. ";
-            return;
-        }
-
-        struct dirent *file;
-        while ((file = readdir(dir)) != NULL) {
-            if (!isInstrumentationLib(file))
-                continue;
-
-            void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
-            char *error;
-            if (handle == nullptr) {
-                LOG(WARNING) << "couldn't load file: " << file->d_name
-                    << " error: " << dlerror();
-                continue;
-            }
-
-            dlerror(); /* Clear any existing error */
-
-            using cb_fun = void (*)(
-                    const InstrumentationEvent,
-                    const char *,
-                    const char *,
-                    const char *,
-                    const char *,
-                    std::vector<void *> *);
-            FQName package_name = FQName(mInstrumentationLibPackage);
-            auto cb = (cb_fun)dlsym(handle, ("HIDL_INSTRUMENTATION_FUNCTION_"
-                        + package_name.tokenName() + "_"
-                        + mInterfaceName).c_str());
-            if ((error = dlerror()) != NULL) {
-                LOG(WARNING)
-                    << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION_"
-                    << mInterfaceName << ", error: " << error;
-                continue;
-            }
-            instrumentationCallbacks->push_back(cb);
-            LOG(INFO) << "Register instrumentation callback from "
-                << file->d_name;
-        }
-        closedir(dir);
-    }
-#else
-    // No-op for user builds.
-    return;
-#endif
-}
-
-bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
-    if (file->d_type != DT_REG) return false;
-    std::cmatch cm;
-    std::regex e("^" + mInstrumentationLibPackage + "(.*).profiler.so$");
-    if (std::regex_match(file->d_name, cm, e)) return true;
-#endif
-    return false;
-}
-
 }  // namespace hardware
 }  // namespace android
 
diff --git a/base/include/hidl/HidlInternal.h b/base/include/hidl/HidlInternal.h
index 1d6c035..80543c0 100644
--- a/base/include/hidl/HidlInternal.h
+++ b/base/include/hidl/HidlInternal.h
@@ -18,6 +18,10 @@
 #define ANDROID_HIDL_INTERNAL_H
 
 #include <cstdint>
+#include <dirent.h>
+#include <functional>
+#include <string>
+#include <vector>
 #include <utility>
 
 namespace android {
@@ -41,7 +45,7 @@
 template<typename T>
 struct hidl_pointer {
     hidl_pointer()
-        : mPointer(nullptr) {
+        : _pad(0) {
     }
     hidl_pointer(T* ptr)
         : mPointer(ptr) {
@@ -93,6 +97,84 @@
     };
 };
 
+#if defined(__LP64__)
+#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
+#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
+#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
+#else
+#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
+#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
+#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
+#endif
+
+// ----------------------------------------------------------------------
+// Class that provides Hidl instrumentation utilities.
+struct HidlInstrumentor {
+    // Event that triggers the instrumentation. e.g. enter of an API call on
+    // the server/client side, exit of an API call on the server/client side
+    // etc.
+    enum InstrumentationEvent {
+        SERVER_API_ENTRY = 0,
+        SERVER_API_EXIT,
+        CLIENT_API_ENTRY,
+        CLIENT_API_EXIT,
+        SYNC_CALLBACK_ENTRY,
+        SYNC_CALLBACK_EXIT,
+        ASYNC_CALLBACK_ENTRY,
+        ASYNC_CALLBACK_EXIT,
+        PASSTHROUGH_ENTRY,
+        PASSTHROUGH_EXIT,
+    };
+
+    // Signature of the instrumentation callback function.
+    using InstrumentationCallback = std::function<void(
+            const InstrumentationEvent event,
+            const char *package,
+            const char *version,
+            const char *interface,
+            const char *method,
+            std::vector<void *> *args)>;
+
+    explicit HidlInstrumentor(
+            const std::string &package,
+            const std::string &insterface);
+    virtual ~HidlInstrumentor();
+
+ protected:
+    // Set mEnableInstrumentation based on system property
+    // hal.instrumentation.enable, register/de-register instrumentation
+    // callbacks if mEnableInstrumentation is true/false.
+    void configureInstrumentation(bool log=true);
+    // Function that lookup and dynamically loads the hidl instrumentation
+    // libraries and registers the instrumentation callback functions.
+    //
+    // The instrumentation libraries should be stored under any of the following
+    // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
+    // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
+    // follow pattern: ^profilerPrefix(.*).profiler.so$
+    //
+    // Each instrumentation library is expected to implement the instrumentation
+    // function called HIDL_INSTRUMENTATION_FUNCTION.
+    //
+    // A no-op for user build.
+    void registerInstrumentationCallbacks(
+            std::vector<InstrumentationCallback> *instrumentationCallbacks);
+
+    // Utility function to determine whether a give file is a instrumentation
+    // library (i.e. the file name follow the expected pattern).
+    bool isInstrumentationLib(const dirent *file);
+
+    // A list of registered instrumentation callbacks.
+    std::vector<InstrumentationCallback> mInstrumentationCallbacks;
+    // Flag whether to enable instrumentation.
+    bool mEnableInstrumentation;
+    // Prefix to lookup the instrumentation libraries.
+    std::string mInstrumentationLibPackage;
+    // Used for dlsym to load the profiling method for given interface.
+    std::string mInterfaceName;
+
+};
+
 }  // namespace details
 }  // namespace hardware
 }  // namespace android
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 17951f7..80f95b6 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -19,11 +19,8 @@
 
 #include <algorithm>
 #include <array>
-#include <dirent.h>
 #include <iterator>
 #include <cutils/native_handle.h>
-#include <cutils/properties.h>
-#include <functional>
 #include <hidl/HidlInternal.h>
 #include <hidl/Status.h>
 #include <map>
@@ -157,8 +154,6 @@
     // to maintain this hidl_string alive.
     operator const char *() const;
 
-    bool operator< (const hidl_string &rhs) const;
-
     void clear();
 
     // Reference an external char array. Ownership is _not_ transferred.
@@ -181,29 +176,25 @@
     void moveFrom(hidl_string &&);
 };
 
-inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) {
-    return strcmp(hs1.c_str(), hs2.c_str()) == 0;
-}
+#define HIDL_STRING_OPERATOR(OP)                                               \
+    inline bool operator OP(const hidl_string &hs1, const hidl_string &hs2) {  \
+        return strcmp(hs1.c_str(), hs2.c_str()) OP 0;                          \
+    }                                                                          \
+    inline bool operator OP(const hidl_string &hs, const char *s) {            \
+        return strcmp(hs.c_str(), s) OP 0;                                     \
+    }                                                                          \
+    inline bool operator OP(const char *s, const hidl_string &hs) {            \
+        return strcmp(hs.c_str(), s) OP 0;                                     \
+    }
 
-inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) {
-    return !(hs1 == hs2);
-}
+HIDL_STRING_OPERATOR(==)
+HIDL_STRING_OPERATOR(!=)
+HIDL_STRING_OPERATOR(<)
+HIDL_STRING_OPERATOR(<=)
+HIDL_STRING_OPERATOR(>)
+HIDL_STRING_OPERATOR(>=)
 
-inline bool operator==(const hidl_string &hs, const char *s) {
-    return strcmp(hs.c_str(), s) == 0;
-}
-
-inline bool operator!=(const hidl_string &hs, const char *s) {
-    return !(hs == s);
-}
-
-inline bool operator==(const char *s, const hidl_string &hs) {
-    return strcmp(hs.c_str(), s) == 0;
-}
-
-inline bool operator!=(const char *s, const hidl_string &hs) {
-    return !(s == hs);
-}
+#undef HIDL_STRING_OPERATOR
 
 // hidl_memory is a structure that can be used to transfer
 // pieces of shared memory between processes. The assumption
@@ -801,84 +792,6 @@
     return hidl_version(major,minor);
 }
 
-#if defined(__LP64__)
-#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
-#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
-#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
-#else
-#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
-#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
-#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
-#endif
-
-// ----------------------------------------------------------------------
-// Class that provides Hidl instrumentation utilities.
-struct HidlInstrumentor {
-    // Event that triggers the instrumentation. e.g. enter of an API call on
-    // the server/client side, exit of an API call on the server/client side
-    // etc.
-    enum InstrumentationEvent {
-        SERVER_API_ENTRY = 0,
-        SERVER_API_EXIT,
-        CLIENT_API_ENTRY,
-        CLIENT_API_EXIT,
-        SYNC_CALLBACK_ENTRY,
-        SYNC_CALLBACK_EXIT,
-        ASYNC_CALLBACK_ENTRY,
-        ASYNC_CALLBACK_EXIT,
-        PASSTHROUGH_ENTRY,
-        PASSTHROUGH_EXIT,
-    };
-
-    // Signature of the instrumentation callback function.
-    using InstrumentationCallback = std::function<void(
-            const InstrumentationEvent event,
-            const char *package,
-            const char *version,
-            const char *interface,
-            const char *method,
-            std::vector<void *> *args)>;
-
-    explicit HidlInstrumentor(
-            const std::string &package,
-            const std::string &insterface);
-    virtual ~HidlInstrumentor();
-
- protected:
-    // Set mEnableInstrumentation based on system property
-    // hal.instrumentation.enable, register/de-register instrumentation
-    // callbacks if mEnableInstrumentation is true/false.
-    void configureInstrumentation(bool log=true);
-    // Function that lookup and dynamically loads the hidl instrumentation
-    // libraries and registers the instrumentation callback functions.
-    //
-    // The instrumentation libraries should be stored under any of the following
-    // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
-    // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
-    // follow pattern: ^profilerPrefix(.*).profiler.so$
-    //
-    // Each instrumentation library is expected to implement the instrumentation
-    // function called HIDL_INSTRUMENTATION_FUNCTION.
-    //
-    // A no-op for user build.
-    void registerInstrumentationCallbacks(
-            std::vector<InstrumentationCallback> *instrumentationCallbacks);
-
-    // Utility function to determine whether a give file is a instrumentation
-    // library (i.e. the file name follow the expected pattern).
-    bool isInstrumentationLib(const dirent *file);
-
-    // A list of registered instrumentation callbacks.
-    std::vector<InstrumentationCallback> mInstrumentationCallbacks;
-    // Flag whether to enable instrumentation.
-    bool mEnableInstrumentation;
-    // Prefix to lookup the instrumentation libraries.
-    std::string mInstrumentationLibPackage;
-    // Used for dlsym to load the profiling method for given interface.
-    std::string mInterfaceName;
-
-};
-
 ///////////////////// toString functions
 
 namespace details {
diff --git a/test_main.cpp b/test_main.cpp
index 6e9bf25..d663391 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -81,9 +81,6 @@
     s.clear(); // should not affect myCString
     EXPECT_STREQ(myCString, "myDString");
 
-    // operator <
-    EXPECT_LT("ab", "bcd");
-
     // casts
     s = "great";
     std::string myString = s;
@@ -101,18 +98,33 @@
     const char * cstrNE = "ABC";
     std::string stringNE(cstrNE);
     hidl_string hsNE(cstrNE);
+    const char * cstr2 = "def";
+    std::string string2(cstr2);
+    hidl_string hs2(cstr2);
+
     EXPECT_TRUE(hs1  == hsE);
-    EXPECT_FALSE(hs1 != hsE);
-    EXPECT_TRUE(hs1  != hsNE);
     EXPECT_FALSE(hs1 == hsNE);
     EXPECT_TRUE(hs1  == cstrE);
-    EXPECT_FALSE(hs1 != cstrE);
-    EXPECT_TRUE(hs1  != cstrNE);
     EXPECT_FALSE(hs1 == cstrNE);
     EXPECT_TRUE(hs1  == stringE);
+    EXPECT_FALSE(hs1 == stringNE);
+    EXPECT_FALSE(hs1 != hsE);
+    EXPECT_TRUE(hs1  != hsNE);
+    EXPECT_FALSE(hs1 != cstrE);
+    EXPECT_TRUE(hs1  != cstrNE);
     EXPECT_FALSE(hs1 != stringE);
     EXPECT_TRUE(hs1  != stringNE);
-    EXPECT_FALSE(hs1 == stringNE);
+
+    EXPECT_TRUE(hs1 < hs2);
+    EXPECT_FALSE(hs2 < hs1);
+    EXPECT_TRUE(hs2 > hs1);
+    EXPECT_FALSE(hs1 > hs2);
+    EXPECT_TRUE(hs1 <= hs1);
+    EXPECT_TRUE(hs1 <= hs2);
+    EXPECT_FALSE(hs2 <= hs1);
+    EXPECT_TRUE(hs1 >= hs1);
+    EXPECT_TRUE(hs2 >= hs1);
+    EXPECT_FALSE(hs2 <= hs1);
 }
 
 TEST_F(LibHidlTest, MemoryTest) {
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index e3cbea4..958b9bd 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -102,6 +102,24 @@
     return false;
 }
 
+static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
+    sp<IServiceManager> binderizedManager = defaultServiceManager();
+    if (binderizedManager == nullptr) {
+        LOG(WARNING) << "Could not registerReference for "
+                     << interfaceName << "/" << instanceName
+                     << ": null binderized manager.";
+        return;
+    }
+    auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName, getpid());
+    if (!ret.isOk()) {
+        LOG(WARNING) << "Could not registerReference for "
+                     << interfaceName << "/" << instanceName
+                     << ": " << ret.description();
+    }
+    LOG(VERBOSE) << "Successfully registerReference for "
+                 << interfaceName << "/" << instanceName;
+}
+
 struct PassthroughServiceManager : IServiceManager {
     Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {
@@ -156,6 +174,9 @@
                        << " but could not find symbol " << sym;
             return nullptr;
         }
+
+        registerReference(fqName, name);
+
         return (*generator)(name);
     }
 
@@ -166,9 +187,20 @@
         return false;
     }
 
-    Return<void> list(list_cb /* _hidl_cb */) override {
-        // TODO: add this functionality
-        LOG(FATAL) << "Cannot list services with passthrough service manager.";
+    Return<void> list(list_cb _hidl_cb) override {
+        std::vector<hidl_string> vec;
+        for (const std::string &path : {
+            HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM
+        }) {
+            std::vector<std::string> libs = search(path, "", ".so");
+            for (const std::string &lib : libs) {
+                std::string matchedName;
+                if (matchPackageName(lib, &matchedName)) {
+                    vec.push_back(matchedName + "/*");
+                }
+            }
+        }
+        _hidl_cb(vec);
         return Void();
     }
     Return<void> listByInterface(const hidl_string& /* fqInstanceName */,
@@ -186,25 +218,17 @@
         return false;
     }
 
-    Return<void> debugDump(debugDump_cb _cb) override {
-        std::vector<InstanceDebugInfo> vec;
-        for (const std::string &path : {
-            HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM
-        }) {
-            std::vector<std::string> libs = search(path, "", ".so");
-            for (const std::string &lib : libs) {
-                std::string matchedName;
-                if (matchPackageName(lib, &matchedName)) {
-                    vec.push_back({
-                        .interfaceName = matchedName,
-                        .instanceName = "",
-                        .pid = -1,
-                        .ptr = 0,
-                    });
-                }
-            }
-        }
-        _cb(vec);
+    Return<void> debugDump(debugDump_cb) override {
+        // This makes no sense.
+        LOG(FATAL) << "Cannot call debugDump on passthrough service manager."
+                   << "Call it on defaultServiceManager() instead.";
+        return Void();
+    }
+
+    Return<void> registerPassthroughClient(const hidl_string &, const hidl_string &, int32_t) override {
+        // This makes no sense.
+        LOG(FATAL) << "Cannot call registerPassthroughClient on passthrough service manager. "
+                   << "Call it on defaultServiceManager() instead.";
         return Void();
     }
 
diff --git a/transport/base/1.0/IBase.hal b/transport/base/1.0/IBase.hal
index 3eae7ea..9301c65 100644
--- a/transport/base/1.0/IBase.hal
+++ b/transport/base/1.0/IBase.hal
@@ -30,6 +30,12 @@
 interface IBase {
 
     /*
+     * Provides way to determine if interface is running without requesting
+     * any functionality.
+     */
+    ping();
+
+    /*
      * Provides run-time type information for this object.
      * For example, for the following interface definition:
      *     package android.hardware.foo@1.0;
diff --git a/transport/manager/1.0/IServiceManager.hal b/transport/manager/1.0/IServiceManager.hal
index 2eafed0..3b292a4 100644
--- a/transport/manager/1.0/IServiceManager.hal
+++ b/transport/manager/1.0/IServiceManager.hal
@@ -111,10 +111,7 @@
     struct InstanceDebugInfo {
         string interfaceName;
         string instanceName;
-        // negative values means N/A.
-        int32_t pid;
-        // 0 means N/A.
-        uint64_t ptr;
+        vec<int32_t> clientPids;
     };
 
     /*
@@ -123,4 +120,13 @@
      *         instance.
      */
     debugDump() generates (vec<InstanceDebugInfo> info);
+
+    /*
+     * When the passthrough service manager returns a service via
+     * get(string, string), it must dispatch a registerPassthroughClient call
+     * to the binderized service manager to indicate which process has called
+     * get. Binderized service manager must record this PID, which can
+     * be retrieved via debugDump.
+     */
+    oneway registerPassthroughClient(string fqName, string name, int32_t pid);
 };
diff --git a/transport/memory/1.0/IMemory.hal b/transport/memory/1.0/IMemory.hal
index 404675a..66f37b3 100644
--- a/transport/memory/1.0/IMemory.hal
+++ b/transport/memory/1.0/IMemory.hal
@@ -19,12 +19,24 @@
 interface IMemory {
 
     /**
-     * Notify that you are about to use this memory.
+     * Notify that you are about to use all of this memory.
      */
     update();
 
     /**
+     * Notify that you are about to use the specific range.
+     *
+     * start + length must be < size
+     *
+     * @param start Offset from start of buffer about to be updated.
+     * @param length Number of bytes to be updated.
+     */
+    updateRange(uint64_t start, uint64_t length);
+
+    /**
      * Notify that you are done modifying this memory.
+     *
+     * Must commit all previous update's and updateAll's.
      */
     commit();
 
diff --git a/transport/memory/1.0/default/AshmemMemory.cpp b/transport/memory/1.0/default/AshmemMemory.cpp
index 31626ea..b954bad 100644
--- a/transport/memory/1.0/default/AshmemMemory.cpp
+++ b/transport/memory/1.0/default/AshmemMemory.cpp
@@ -37,12 +37,17 @@
 
 // Methods from ::android::hidl::memory::V1_0::IMemory follow.
 Return<void> AshmemMemory::update() {
-    // NOOP
+    // NOOP (since non-remoted memory)
+    return Void();
+}
+
+Return<void> AshmemMemory::updateRange(uint64_t start, uint64_t length) {
+    // NOOP (since non-remoted memory)
     return Void();
 }
 
 Return<void> AshmemMemory::commit() {
-    // NOOP
+    // NOOP (since non-remoted memory)
     return Void();
 }
 
diff --git a/transport/memory/1.0/default/AshmemMemory.h b/transport/memory/1.0/default/AshmemMemory.h
index 9dbe1fe..825d74e 100644
--- a/transport/memory/1.0/default/AshmemMemory.h
+++ b/transport/memory/1.0/default/AshmemMemory.h
@@ -43,6 +43,7 @@
 
     // Methods from ::android::hidl::memory::V1_0::IMemory follow.
     Return<void> update() override;
+    Return<void> updateRange(uint64_t start, uint64_t length) override;
     Return<void> commit() override;
     Return<void*> getPointer() override;
     Return<uint64_t> getSize() override;