Snap for 6439596 from 87d7ad9d8fe6cbb0405983b37ff9e79927451bc7 to qt-aml-tzdata-release

Change-Id: I410d82f717bc22d5640b0d86ac1fde47169456a6
diff --git a/Android.bp b/Android.bp
index 9207656..727f07f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -22,21 +22,8 @@
     ],
 }
 
-phony {
-    name: "libhidl",
-    required: [
-        "libhidlbase",
-    ],
-}
-
-cc_library_headers {
-    name: "libhidl_gtest_helper",
-    export_include_dirs: ["gtest_helper"],
-}
-
 cc_test {
     name: "libhidl_test",
-    host_supported: true,
     defaults: ["libhidl-defaults"],
     gtest: false,
     srcs: ["test_main.cpp"],
@@ -46,6 +33,8 @@
         "android.hidl.memory@1.0",
         "libbase",
         "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
         "liblog",
         "libutils",
         "libcutils",
@@ -76,7 +65,6 @@
 cc_library {
     name: "libhidlbase",
     defaults: ["libhidlbase-combined-impl"],
-    host_supported: true,
     recovery_available: true,
     vendor_available: true,
     vndk: {
@@ -101,8 +89,6 @@
     whole_static_libs: [
         "libhwbinder_pgo-impl-internal",
     ],
-
-    visibility: ["//system/libhwbinder:__subpackages__"],
 }
 
 // WARNING: deprecated
@@ -110,5 +96,10 @@
 // on libhidlbase instead.
 cc_library {
     name: "libhidltransport",
+    recovery_available: true,
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index c4a663e..3e17fc4 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,9 +2,6 @@
   "presubmit": [
     {
       "name": "libhidl_test"
-    },
-    {
-      "name": "hidl_implementation_test"
     }
   ]
 }
diff --git a/adapter/Android.bp b/adapter/Android.bp
index ae801bc..eb322bc 100644
--- a/adapter/Android.bp
+++ b/adapter/Android.bp
@@ -23,11 +23,14 @@
     shared_libs: [
         "libbase",
         "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
         "liblog",
         "libutils",
     ],
     export_shared_lib_headers: [
         "libhidlbase",
+        "libhidltransport",
         "libutils",
     ],
 }
diff --git a/base/Android.bp b/base/Android.bp
index ca4e259..8fe2702 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -28,9 +28,8 @@
 
 cc_library {
     name: "libhidlbase-impl-internal",
-    host_supported: true,
-    recovery_available: true,
     vendor_available: true,
+    recovery_available: true,
     defaults: [
         "libhidlbase-impl-shared-libs",
         "libhidl-defaults"
@@ -54,6 +53,4 @@
             cflags: ["-DLIBHIDL_TARGET_DEBUGGABLE"],
         },
     },
-
-    visibility: ["//system/libhidl:__subpackages__"],
 }
diff --git a/base/HidlInternal.cpp b/base/HidlInternal.cpp
index 956effd..440b30f 100644
--- a/base/HidlInternal.cpp
+++ b/base/HidlInternal.cpp
@@ -21,6 +21,7 @@
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
+#include <cutils/properties.h>
 
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
 #include <dirent.h>
@@ -55,7 +56,7 @@
     // "0" means the vndkVersion must be initialized with the property value.
     // Otherwise, return the value.
     if (vndkVersion == "0") {
-        vndkVersion = base::GetProperty("ro.vndk.version", "");
+        vndkVersion = android::base::GetProperty("ro.vndk.version", "");
         if (vndkVersion != "" && vndkVersion != "current") {
             vndkVersion = "-" + vndkVersion;
         } else {
@@ -75,44 +76,44 @@
     configureInstrumentation(false);
     if (__sanitizer_cov_dump != nullptr) {
         ::android::add_sysprop_change_callback(
-                []() {
-                    bool enableCoverage = base::GetBoolProperty(kSysPropHalCoverage, false);
-                    if (enableCoverage) {
-                        __sanitizer_cov_dump();
-                    }
-                },
-                0);
+            []() {
+                bool enableCoverage = property_get_bool(kSysPropHalCoverage, false);
+                if (enableCoverage) {
+                    __sanitizer_cov_dump();
+                }
+            },
+            0);
     }
-    if (base::GetBoolProperty("ro.vts.coverage", false)) {
+    if (property_get_bool("ro.vts.coverage", false)) {
         const char* prefixOverride = getenv(kGcovPrefixOverrideEnvVar);
         if (prefixOverride == nullptr || strcmp(prefixOverride, "true") != 0) {
             const std::string gcovPath = kGcovPrefixPath + std::to_string(getpid());
             setenv(kGcovPrefixEnvVar, gcovPath.c_str(), true /* overwrite */);
         }
         ::android::add_sysprop_change_callback(
-                []() {
-                    const bool enableCoverage = base::GetBoolProperty(kSysPropHalCoverage, false);
-                    if (enableCoverage) {
-                        dl_iterate_phdr(
-                                [](struct dl_phdr_info* info, size_t /* size */, void* /* data */) {
-                                    if (strlen(info->dlpi_name) == 0) return 0;
+            []() {
+                const bool enableCoverage = property_get_bool(kSysPropHalCoverage, false);
+                if (enableCoverage) {
+                    dl_iterate_phdr(
+                        [](struct dl_phdr_info* info, size_t /* size */, void* /* data */) {
+                            if (strlen(info->dlpi_name) == 0) return 0;
 
-                                    void* handle = dlopen(info->dlpi_name, RTLD_LAZY);
-                                    if (handle == nullptr) {
-                                        LOG(INFO) << "coverage dlopen failed: " << dlerror();
-                                        return 0;
-                                    }
-                                    void (*flush)() = (void (*)())dlsym(handle, "__gcov_flush");
-                                    if (flush == nullptr) {
-                                        return 0;
-                                    }
-                                    flush();
-                                    return 0;
-                                },
-                                nullptr /* data */);
-                    }
-                },
-                0 /* priority */);
+                            void* handle = dlopen(info->dlpi_name, RTLD_LAZY);
+                            if (handle == nullptr) {
+                                LOG(INFO) << "coverage dlopen failed: " << dlerror();
+                                return 0;
+                            }
+                            void (*flush)() = (void (*)())dlsym(handle, "__gcov_flush");
+                            if (flush == nullptr) {
+                                return 0;
+                            }
+                            flush();
+                            return 0;
+                        },
+                        nullptr /* data */);
+                }
+            },
+            0 /* priority */);
     }
 #endif
 }
@@ -120,7 +121,7 @@
 HidlInstrumentor::~HidlInstrumentor() {}
 
 void HidlInstrumentor::configureInstrumentation(bool log) {
-    mEnableInstrumentation = base::GetBoolProperty("hal.instrumentation.enable", false);
+    mEnableInstrumentation = property_get_bool("hal.instrumentation.enable", false);
     if (mEnableInstrumentation) {
         if (log) {
             LOG(INFO) << "Enable instrumentation.";
@@ -139,8 +140,8 @@
         std::vector<InstrumentationCallback> *instrumentationCallbacks) {
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
     std::vector<std::string> instrumentationLibPaths;
-    const std::string instrumentationLibPath = base::GetProperty(kSysPropInstrumentationPath, "");
-    if (instrumentationLibPath.size() > 0) {
+    char instrumentationLibPath[PROPERTY_VALUE_MAX];
+    if (property_get(kSysPropInstrumentationPath, instrumentationLibPath, "") > 0) {
         instrumentationLibPaths.push_back(instrumentationLibPath);
     } else {
         static std::string halLibPathVndkSp = android::base::StringPrintf(
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index af805b9..f97f216 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -35,8 +35,10 @@
 }
 }  // namespace details
 
-hidl_handle::hidl_handle() : mHandle(nullptr), mOwnsHandle(false) {
-    memset(mPad, 0, sizeof(mPad));
+hidl_handle::hidl_handle() {
+    memset(this, 0, sizeof(*this));
+    // mHandle = nullptr;
+    // mOwnsHandle = false;
 }
 
 hidl_handle::~hidl_handle() {
@@ -136,8 +138,11 @@
 
 static const char *const kEmptyString = "";
 
-hidl_string::hidl_string() : mBuffer(kEmptyString), mSize(0), mOwnsBuffer(false) {
-    memset(mPad, 0, sizeof(mPad));
+hidl_string::hidl_string() {
+    memset(this, 0, sizeof(*this));
+    // mSize is zero
+    // mOwnsBuffer is false
+    mBuffer = kEmptyString;
 }
 
 hidl_string::~hidl_string() {
diff --git a/base/Status.cpp b/base/Status.cpp
index 7698ff8..90474a0 100644
--- a/base/Status.cpp
+++ b/base/Status.cpp
@@ -149,34 +149,9 @@
 }
 
 namespace details {
-    void return_status::onValueRetrieval() const {
-        if (!isOk()) {
-            LOG(FATAL) << "Attempted to retrieve value from failed HIDL call: " << description();
-        }
-    }
-
-    void return_status::onIgnored() const {
-        if (gReturnRestriction == HidlReturnRestriction::NONE) {
-            return;
-        }
-
-        if (gReturnRestriction == HidlReturnRestriction::ERROR_IF_UNCHECKED) {
-            LOG(ERROR) << "Failed to check status of HIDL Return.";
-            CallStack::logStack("unchecked HIDL return", CallStack::getCurrent(10).get(),
-                                ANDROID_LOG_ERROR);
-        } else {
-            LOG(FATAL) << "Failed to check status of HIDL Return.";
-        }
-    }
-
     void return_status::assertOk() const {
         if (!isOk()) {
-            LOG(FATAL) << "Failed HIDL return status not checked. Usually this happens because of "
-                          "a transport error (error parceling, binder driver, or from unparceling)"
-                          ". If you see this in code calling into \"Bn\" classes in for a HAL "
-                          "server process, then it is likely that the code there is returning "
-                          "transport errors there (as opposed to errors defined within its "
-                          "protocol). Error is: " << description();
+            LOG(FATAL) << "Attempted to retrieve value from failed HIDL call: " << description();
         }
     }
 
@@ -184,16 +159,26 @@
         // mCheckedStatus must be checked before isOk since isOk modifies mCheckedStatus
         if (mCheckedStatus) return;
 
-        assertOk();
-        onIgnored();
+        if (!isOk()) {
+            LOG(FATAL) << "Failed HIDL return status not checked: " << description();
+        }
+
+        if (gReturnRestriction == HidlReturnRestriction::NONE) {
+            return;
+        }
+
+        if (gReturnRestriction == HidlReturnRestriction::ERROR_IF_UNCHECKED) {
+            LOG(ERROR) << "Failed to check status of HIDL Return.";
+            CallStack::logStack("unchecked HIDL return", CallStack::getCurrent(10).get(), ANDROID_LOG_ERROR);
+        } else {
+            LOG(FATAL) << "Failed to check status of HIDL Return.";
+        }
     }
 
     return_status& return_status::operator=(return_status&& other) noexcept {
-        if (!mCheckedStatus) {
-            assertOk();
-            onIgnored();
+        if (!mCheckedStatus && !isOk()) {
+            LOG(FATAL) << "Failed HIDL return status not checked: " << description();
         }
-
         std::swap(mStatus, other.mStatus);
         std::swap(mCheckedStatus, other.mCheckedStatus);
         return *this;
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 1b91c26..93a6251 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -20,24 +20,18 @@
 #include <algorithm>
 #include <array>
 #include <iterator>
+#include <cutils/native_handle.h>
 #include <hidl/HidlInternal.h>
+#include <hidl/Status.h>
 #include <map>
 #include <sstream>
 #include <stddef.h>
 #include <tuple>
 #include <type_traits>
-#include <vector>
-
-// no requirements on types not used in scatter/gather
-// no requirements on other libraries
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#include <cutils/native_handle.h>
-#include <hidl/Status.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/StrongPointer.h>
-#pragma clang diagnostic pop
+#include <vector>
 
 namespace android {
 
@@ -129,9 +123,8 @@
 private:
     void freeHandle();
 
-    details::hidl_pointer<const native_handle_t> mHandle;
-    bool mOwnsHandle;
-    uint8_t mPad[7];
+    details::hidl_pointer<const native_handle_t> mHandle __attribute__ ((aligned(8)));
+    bool mOwnsHandle __attribute ((aligned(8)));
 };
 
 struct hidl_string {
@@ -181,7 +174,6 @@
     details::hidl_pointer<const char> mBuffer;
     uint32_t mSize;  // NOT including the terminating '\0'.
     bool mOwnsBuffer; // if true then mBuffer is a mutable char *
-    uint8_t mPad[3];
 
     // copy from data with size. Assume that my memory is freed
     // (through clear(), for example)
@@ -302,9 +294,9 @@
     static const size_t kOffsetOfName;
 
 private:
-    hidl_handle mHandle;
-    uint64_t mSize;
-    hidl_string mName;
+    hidl_handle mHandle __attribute__ ((aligned(8)));
+    uint64_t mSize __attribute__ ((aligned(8)));
+    hidl_string mName __attribute__ ((aligned(8)));
 };
 
 // HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
@@ -334,12 +326,15 @@
 
 template<typename T>
 struct hidl_vec {
-    using value_type = T;
-
-    hidl_vec() : mBuffer(nullptr), mSize(0), mOwnsBuffer(false) {
+    hidl_vec() {
         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
 
-        memset(mPad, 0, sizeof(mPad));
+        memset(this, 0, sizeof(*this));
+        // mSize is 0
+        // mBuffer is nullptr
+
+        // this is for consistency with the original implementation
+        mOwnsBuffer = true;
     }
 
     // Note, does not initialize primitive types.
@@ -515,7 +510,7 @@
         T* newBuffer = new T[size]();
 
         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
-            newBuffer[i] = std::move(mBuffer[i]);
+            newBuffer[i] = mBuffer[i];
         }
 
         if (mOwnsBuffer) {
@@ -576,15 +571,11 @@
     iterator end() { return data()+mSize; }
     const_iterator begin() const { return data(); }
     const_iterator end() const { return data()+mSize; }
-    iterator find(const T& v) { return std::find(begin(), end(), v); }
-    const_iterator find(const T& v) const { return std::find(begin(), end(), v); }
-    bool contains(const T& v) const { return find(v) != end(); }
 
-  private:
+private:
     details::hidl_pointer<T> mBuffer;
     uint32_t mSize;
     bool mOwnsBuffer;
-    uint8_t mPad[3];
 
     // copy from an array-like object, assuming my resources are freed.
     template <typename Array>
@@ -740,8 +731,6 @@
     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
 
     hidl_array() = default;
-    hidl_array(const hidl_array&) noexcept = default;
-    hidl_array(hidl_array&&) noexcept = default;
 
     // Copies the data from source, using T::operator=(const T &).
     hidl_array(const T *source) {
@@ -756,9 +745,6 @@
         modifier = array;
     }
 
-    hidl_array& operator=(const hidl_array&) noexcept = default;
-    hidl_array& operator=(hidl_array&&) noexcept = default;
-
     T *data() { return mBuffer; }
     const T *data() const { return mBuffer; }
 
@@ -807,12 +793,10 @@
 // An array of T's. Assumes that T::operator=(const T &) is defined.
 template<typename T, size_t SIZE1>
 struct hidl_array<T, SIZE1> {
-    using value_type = T;
+
     using std_array_type = typename details::std_array<T, SIZE1>::type;
 
     hidl_array() = default;
-    hidl_array(const hidl_array&) noexcept = default;
-    hidl_array(hidl_array&&) noexcept = default;
 
     // Copies the data from source, using T::operator=(const T &).
     hidl_array(const T *source) {
@@ -824,9 +808,6 @@
     // Copies the data from the given std::array, using T::operator=(const T &).
     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
 
-    hidl_array& operator=(const hidl_array&) noexcept = default;
-    hidl_array& operator=(hidl_array&&) noexcept = default;
-
     T *data() { return mBuffer; }
     const T *data() const { return mBuffer; }
 
diff --git a/base/include/hidl/Status.h b/base/include/hidl/Status.h
index 74901bb..817277f 100644
--- a/base/include/hidl/Status.h
+++ b/base/include/hidl/Status.h
@@ -141,15 +141,8 @@
         Status mStatus {};
         mutable bool mCheckedStatus = false;
 
-        // called when an unchecked status is discarded
-        // makes sure this status is checked according to the preference
-        // set by setProcessHidlReturnRestriction
-        void onIgnored() const;
-
         template <typename T, typename U>
         friend Return<U> StatusOf(const Return<T> &other);
-    protected:
-        void onValueRetrieval() const;
     public:
         void assertOk() const;
         return_status() {}
@@ -231,7 +224,7 @@
     ~Return() = default;
 
     operator T() const {
-        onValueRetrieval();  // assert okay
+        assertOk();
         return mVal;
     }
 
@@ -260,7 +253,7 @@
     ~Return() = default;
 
     operator sp<T>() const {
-        onValueRetrieval();  // assert okay
+        assertOk();
         return mVal;
     }
 
diff --git a/gtest_helper/hidl/GtestPrinter.h b/gtest_helper/hidl/GtestPrinter.h
deleted file mode 100644
index 4b5ac2d..0000000
--- a/gtest_helper/hidl/GtestPrinter.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace hardware {
-
-static inline std::string Sanitize(std::string name) {
-    for (size_t i = 0; i < name.size(); i++) {
-        // gtest test names must only contain alphanumeric characters
-        if (!std::isalnum(name[i])) name[i] = '_';
-    }
-    return name;
-}
-
-static inline std::string PrintInstanceNameToString(
-        const testing::TestParamInfo<std::string>& info) {
-    // test names need to be unique -> index prefix
-    std::string name = std::to_string(info.index) + "/" + info.param;
-    return Sanitize(name);
-}
-
-template <typename... T>
-static inline std::string PrintInstanceTupleNameToString(
-        const testing::TestParamInfo<std::tuple<T...>>& info) {
-    std::vector<std::string> instances = std::apply(
-            [](auto&&... elems) {
-                std::vector<std::string> instances;
-                instances.reserve(sizeof...(elems));
-                (instances.push_back(std::forward<decltype(elems)>(elems)), ...);
-                return instances;
-            },
-            info.param);
-    std::string param_string;
-    for (const std::string& instance : instances) {
-        param_string += instance + "_";
-    }
-    param_string += std::to_string(info.index);
-
-    return Sanitize(param_string);
-}
-
-}  // namespace hardware
-}  // namespace android
diff --git a/libhidlcache/Android.bp b/libhidlcache/Android.bp
new file mode 100644
index 0000000..d28a4f1
--- /dev/null
+++ b/libhidlcache/Android.bp
@@ -0,0 +1,71 @@
+// 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.
+
+cc_library {
+    name: "libhidlcache",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    defaults: ["libhidl-defaults"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhwbinder",
+        "libhidltransport",
+        "android.hidl.memory@1.0",
+        "android.hidl.memory.block@1.0",
+        "android.hidl.memory.token@1.0",
+    ],
+    export_include_dirs: ["include"],
+
+    export_shared_lib_headers: [
+        "android.hidl.memory@1.0",
+        "android.hidl.memory.block@1.0",
+        "android.hidl.memory.token@1.0",
+        "libhidlbase",
+    ],
+    srcs: [
+        "HidlMemoryCache.cpp",
+        "MemoryDealer.cpp",
+        "mapping.cpp",
+    ],
+}
+
+cc_test {
+    name: "libhidlcache_test",
+    defaults: ["hidl-gen-defaults"],
+
+    shared_libs: [
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "android.hidl.memory.block@1.0",
+        "android.hidl.memory.token@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidlcache",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+
+    srcs: ["libhidlcache_test.cpp"],
+}
diff --git a/libhidlcache/HidlCache.h b/libhidlcache/HidlCache.h
new file mode 100644
index 0000000..39a7b3a
--- /dev/null
+++ b/libhidlcache/HidlCache.h
@@ -0,0 +1,143 @@
+/*
+ * 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_HARDWARE_HIDL_CACHE_H
+#define ANDROID_HARDWARE_HIDL_CACHE_H
+
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+
+// A generic cache to map Key to sp<Value>. The cache records are kept with
+// wp<Value>, so that it does not block the Value to be garbage collected
+// when there's no other sp<> externally.
+template <class Key, class Value, class Compare = std::less<Key>>
+class HidlCache : public virtual RefBase {
+    using Mutex = std::mutex;
+    using Lock = std::lock_guard<Mutex>;
+
+   public:
+    //  A RAII class to manage lock/unlock HidlCache.
+    class HidlCacheLock : public virtual RefBase {
+       public:
+        HidlCacheLock(sp<HidlCache> cache, const Key& key) : mCache(cache), mKey(key) {
+            mCache->lock(mKey);
+        }
+        ~HidlCacheLock() { mCache->unlock(mKey); }
+
+       private:
+        sp<HidlCache> mCache;
+        const Key mKey;
+    };
+    // lock the IMemory refered by key and keep it alive even if there's no
+    // other memory block refers to.
+    virtual bool lock(const Key& key);
+    virtual sp<Value> unlock(const Key& key);
+    virtual bool flush(const Key& key);
+    // fetch the sp<Value> with key from cache,
+    // make a new instance with fill() if it does not present currently.
+    virtual sp<Value> fetch(const Key& key);
+    virtual sp<HidlCacheLock> lockGuard(const Key& key) { return new HidlCacheLock(this, key); }
+
+    virtual ~HidlCache() {}
+
+   protected:
+    friend void HidlCacheWhiteBoxTest();
+    // This method shall be called with a lock held
+    virtual sp<Value> fillLocked(const Key& key) = 0;
+
+    // @return nullptr if it does not present currently.
+    // @note This method shall be called with a lock held
+    virtual sp<Value> getCachedLocked(const Key& key);
+    bool cached(Key key) const { return mCached.count(key) > 0; }
+    bool locked(Key key) const { return mLocked.count(key) > 0; }
+    Mutex mMutex;
+
+    std::map<Key, wp<Value>, Compare> mCached;
+    std::map<Key, sp<Value>, Compare> mLocked;
+};
+
+template <class Key, class Value, class Compare>
+bool HidlCache<Key, Value, Compare>::lock(const Key& key) {
+    {
+        Lock lock(mMutex);
+        if (cached(key)) {
+            sp<Value> im = mCached[key].promote();
+            if (im != nullptr) {
+                mLocked[key] = im;
+                return true;
+            } else {
+                mCached.erase(key);
+            }
+        }
+    }
+    sp<Value> value = fetch(key);
+    if (value == nullptr) {
+        return false;
+    } else {
+        Lock lock(mMutex);
+        mLocked[key] = value;
+        return true;
+    }
+}
+
+template <class Key, class Value, class Compare>
+sp<Value> HidlCache<Key, Value, Compare>::unlock(const Key& key) {
+    Lock lock(mMutex);
+    if (locked(key)) {
+        sp<Value> v = mLocked[key];
+        mLocked.erase(key);
+        return v;
+    }
+    return nullptr;
+}
+
+template <class Key, class Value, class Compare>
+bool HidlCache<Key, Value, Compare>::flush(const Key& key) {
+    Lock lock(mMutex);
+    bool contain = cached(key);
+    mCached.erase(key);
+    return contain;
+}
+
+template <class Key, class Value, class Compare>
+sp<Value> HidlCache<Key, Value, Compare>::getCachedLocked(const Key& key) {
+    if (cached(key)) {
+        wp<Value> cache = mCached[key];
+        sp<Value> mem = cache.promote();
+        if (mem != nullptr) {
+            return mem;
+        } else {
+            mCached.erase(key);
+        }
+    }
+    return nullptr;
+}
+
+template <class Key, class Value, class Compare>
+sp<Value> HidlCache<Key, Value, Compare>::fetch(const Key& key) {
+    Lock lock(mMutex);
+    sp<Value> value = getCachedLocked(key);
+
+    if (value == nullptr) {
+        value = fillLocked(key);
+    }
+    return value;
+}
+
+}  // namespace hardware
+}  // namespace android
+#endif
diff --git a/libhidlcache/HidlMemoryCache.cpp b/libhidlcache/HidlMemoryCache.cpp
new file mode 100644
index 0000000..a23c388
--- /dev/null
+++ b/libhidlcache/HidlMemoryCache.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "HidlMemoryCache"
+#include "HidlMemoryCache.h"
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/hidl/memory/token/1.0/IMemoryToken.h>
+#include <hidlmemory/mapping.h>
+#include <sys/mman.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+
+using IMemoryToken = ::android::hidl::memory::token::V1_0::IMemoryToken;
+using IMemory = ::android::hidl::memory::V1_0::IMemory;
+
+class MemoryDecorator : public virtual IMemory {
+   public:
+    MemoryDecorator(const sp<IMemory>& heap) : mHeap(heap) {}
+    virtual ~MemoryDecorator() {}
+    Return<void> update() override { return mHeap->update(); }
+    Return<void> read() override { return mHeap->read(); }
+    Return<void> updateRange(uint64_t start, uint64_t length) override {
+        return mHeap->updateRange(start, length);
+    }
+    Return<void> readRange(uint64_t start, uint64_t length) override {
+        return mHeap->readRange(start, length);
+    }
+    Return<void> commit() override { return mHeap->commit(); }
+
+    Return<void*> getPointer() override { return mHeap->getPointer(); }
+    Return<uint64_t> getSize() override { return mHeap->getSize(); }
+
+   protected:
+    sp<IMemory> mHeap;
+};
+
+class MemoryCacheable : public virtual MemoryDecorator {
+   public:
+    MemoryCacheable(const sp<IMemory>& heap, sp<IMemoryToken> key)
+        : MemoryDecorator(heap), mKey(key) {}
+    virtual ~MemoryCacheable() { HidlMemoryCache::getInstance()->flush(mKey); }
+
+   protected:
+    sp<IMemoryToken> mKey;
+};
+
+class MemoryBlockImpl : public virtual IMemory {
+   public:
+    MemoryBlockImpl(const sp<IMemory>& heap, uint64_t size, uint64_t offset)
+        : mHeap(heap), mSize(size), mOffset(offset), mHeapSize(heap->getSize()) {}
+    bool validRange(uint64_t start, uint64_t length) {
+        return (start + length <= mSize) && (start + length >= start) &&
+               (mOffset + mSize <= mHeapSize);
+    }
+    Return<void> readRange(uint64_t start, uint64_t length) override {
+        if (!validRange(start, length)) {
+            ALOGE("IMemoryBlock::readRange: out of range");
+            return Void();
+        }
+        return mHeap->readRange(mOffset + start, length);
+    }
+    Return<void> updateRange(uint64_t start, uint64_t length) override {
+        if (!validRange(start, length)) {
+            ALOGE("IMemoryBlock::updateRange: out of range");
+            return Void();
+        }
+        return mHeap->updateRange(mOffset + start, length);
+    }
+    Return<void> read() override { return this->readRange(0, mSize); }
+    Return<void> update() override { return this->updateRange(0, mSize); }
+    Return<void> commit() override { return mHeap->commit(); }
+    Return<uint64_t> getSize() override { return mSize; }
+    Return<void*> getPointer() override {
+        void* p = mHeap->getPointer();
+        return (static_cast<char*>(p) + mOffset);
+    }
+
+   protected:
+    sp<IMemory> mHeap;
+    uint64_t mSize;
+    uint64_t mOffset;
+    uint64_t mHeapSize;
+};
+
+sp<HidlMemoryCache> HidlMemoryCache::getInstance() {
+    static sp<HidlMemoryCache> instance = new HidlMemoryCache();
+    return instance;
+}
+
+sp<IMemory> HidlMemoryCache::fillLocked(const sp<IMemoryToken>& key) {
+    sp<IMemory> memory = nullptr;
+    Return<void> ret = key->get(
+        [&](const hidl_memory& mem) { memory = new MemoryCacheable(mapMemory(mem), key); });
+    if (!ret.isOk()) {
+        ALOGE("HidlMemoryCache::fill: cannot IMemoryToken::get.");
+        return nullptr;
+    }
+    mCached[key] = memory;
+    return memory;
+}
+
+sp<IMemory> HidlMemoryCache::map(const MemoryBlock& memblk) {
+    sp<IMemoryToken> token = memblk.token;
+    sp<IMemory> heap = fetch(token);
+    if (heap == nullptr) {
+        return nullptr;
+    }
+    return new MemoryBlockImpl(heap, memblk.size, memblk.offset);
+}
+
+}  // namespace hardware
+}  // namespace android
diff --git a/libhidlcache/HidlMemoryCache.h b/libhidlcache/HidlMemoryCache.h
new file mode 100644
index 0000000..c9a533b
--- /dev/null
+++ b/libhidlcache/HidlMemoryCache.h
@@ -0,0 +1,62 @@
+/*
+ * 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_HARDWARD_HIDLMEMORY_CACHE_H
+#define ANDROID_HARDWARD_HIDLMEMORY_CACHE_H
+
+#include <android/hidl/memory/block/1.0/types.h>
+#include <android/hidl/memory/token/1.0/IMemoryToken.h>
+#include <hidl/HidlBinderSupport.h>
+#include <hwbinder/IBinder.h>
+#include <utils/RefBase.h>
+#include "HidlCache.h"
+
+namespace android {
+namespace hardware {
+
+struct IMemoryTokenCompare {
+    using IMemoryToken = ::android::hidl::memory::token::V1_0::IMemoryToken;
+    bool operator()(const sp<IMemoryToken>& lhs, const sp<IMemoryToken>& rhs) const {
+        sp<IBinder> lb = toBinder<IMemoryToken>(lhs);
+        sp<IBinder> rb = toBinder<IMemoryToken>(rhs);
+        return lb < rb;
+    }
+};
+
+// The HidlMemoryCache is a singleton class to provides cache for
+// IMemoryToken => ::android::hidl::memory::V1_0::IMemory
+// It's an abstraction layer on top of the IMapper and supports, but is
+// not limited to, the Ashmem type HidlMemory.
+class HidlMemoryCache
+    : public virtual HidlCache<sp<::android::hidl::memory::token::V1_0::IMemoryToken>,
+                               ::android::hidl::memory::V1_0::IMemory, IMemoryTokenCompare> {
+    using IMemoryToken = ::android::hidl::memory::token::V1_0::IMemoryToken;
+    using IMemory = ::android::hidl::memory::V1_0::IMemory;
+    using MemoryBlock = ::android::hidl::memory::block::V1_0::MemoryBlock;
+
+   public:
+    virtual sp<IMemory> map(const MemoryBlock& block);
+    // get the singleton
+    static sp<HidlMemoryCache> getInstance();
+
+   protected:
+    HidlMemoryCache() {}
+    virtual sp<IMemory> fillLocked(const sp<IMemoryToken>& key) override;
+};
+
+}  // namespace hardware
+}  // namespace android
+
+#endif
diff --git a/libhidlcache/MemoryDealer.cpp b/libhidlcache/MemoryDealer.cpp
new file mode 100644
index 0000000..e5686a7
--- /dev/null
+++ b/libhidlcache/MemoryDealer.cpp
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+#define LOG_TAG "MemoryDealer"
+
+#include <hidlcache/MemoryDealer.h>
+#include <hidlmemory/HidlMemoryToken.h>
+#include <hidlmemory/mapping.h>
+
+#include <list>
+
+#include <log/log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using std::string;
+
+namespace android {
+namespace hardware {
+
+class SimpleBestFitAllocator {
+    enum { PAGE_ALIGNED = 0x00000001 };
+
+   public:
+    explicit SimpleBestFitAllocator(size_t size);
+    ~SimpleBestFitAllocator();
+
+    size_t allocate(size_t size, uint32_t flags = 0);
+    status_t deallocate(size_t offset);
+    size_t size() const;
+    void dump(const char* tag) const;
+    void dump(string& res, const char* tag) const;
+
+    static size_t getAllocationAlignment() { return kMemoryAlign; }
+
+   private:
+    struct chunk_t {
+        chunk_t(size_t start, size_t size) : start(start), size(size), free(1) {}
+        size_t start;
+        size_t size : 28;
+        int free : 4;
+    };
+    using List = std::list<chunk_t*>;
+    using Iterator = std::list<chunk_t*>::iterator;
+    using IteratorConst = std::list<chunk_t*>::const_iterator;
+    using Mutex = std::mutex;
+    using Lock = std::lock_guard<Mutex>;
+
+    ssize_t alloc(size_t size, uint32_t flags);
+    chunk_t* dealloc(size_t start);
+    void dump_l(const char* tag) const;
+    void dump_l(string& res, const char* tag) const;
+
+    static const int kMemoryAlign;
+    mutable Mutex mLock;
+    List mList;
+    size_t mHeapSize;
+};
+
+MemoryDealer::MemoryDealer(size_t size) : mAllocator(new SimpleBestFitAllocator(size)) {}
+
+MemoryDealer::~MemoryDealer() {
+    delete mAllocator;
+}
+
+ssize_t MemoryDealer::allocateOffset(size_t size) {
+    return mAllocator->allocate(size);
+}
+
+void MemoryDealer::deallocate(size_t offset) {
+    mAllocator->deallocate(offset);
+}
+
+void MemoryDealer::dump(const char* tag) const {
+    mAllocator->dump(tag);
+}
+
+size_t MemoryDealer::getAllocationAlignment() {
+    return SimpleBestFitAllocator::getAllocationAlignment();
+}
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size) {
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize - 1) & ~(pagesize - 1));
+
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.push_front(node);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator() {
+    while (mList.size() != 0) {
+        chunk_t* removed = mList.front();
+        mList.pop_front();
+#ifdef __clang_analyzer__
+        // Clang static analyzer gets confused in this loop
+        // and generates a false positive warning about accessing
+        // memory that is already freed.
+        // Add an "assert" to avoid the confusion.
+        LOG_ALWAYS_FATAL_IF(mList.front() == removed);
+#endif
+        delete removed;
+    }
+}
+
+size_t SimpleBestFitAllocator::size() const {
+    return mHeapSize;
+}
+
+size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags) {
+    Lock lock(mLock);
+    ssize_t offset = alloc(size, flags);
+    return offset;
+}
+
+status_t SimpleBestFitAllocator::deallocate(size_t offset) {
+    Lock lock(mLock);
+    chunk_t const* const freed = dealloc(offset);
+    if (freed) {
+        return NO_ERROR;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags) {
+    if (size == 0) {
+        return 0;
+    }
+    size = (size + kMemoryAlign - 1) / kMemoryAlign;
+    size_t pagesize = getpagesize();
+
+    Iterator free_chunk_p = mList.end();
+    for (Iterator p = mList.begin(); p != mList.end(); p++) {
+        chunk_t* cur = *p;
+        int extra = 0;
+        if (flags & PAGE_ALIGNED) extra = (-cur->start & ((pagesize / kMemoryAlign) - 1));
+
+        // best fit
+        if (cur->free && (cur->size >= (size + extra))) {
+            if ((free_chunk_p == mList.end()) || (cur->size < (*free_chunk_p)->size)) {
+                free_chunk_p = p;
+            }
+            if (cur->size == size) {
+                break;
+            }
+        }
+    }
+    if (free_chunk_p != mList.end()) {
+        chunk_t* free_chunk = *free_chunk_p;
+        const size_t free_size = free_chunk->size;
+        free_chunk->free = 0;
+        free_chunk->size = size;
+        if (free_size > size) {
+            int extra = 0;
+            if (flags & PAGE_ALIGNED)
+                extra = (-free_chunk->start & ((pagesize / kMemoryAlign) - 1));
+            if (extra) {
+                chunk_t* split = new chunk_t(free_chunk->start, extra);
+                free_chunk->start += extra;
+                mList.insert(free_chunk_p, split);
+            }
+
+            ALOGE_IF(
+                (flags & PAGE_ALIGNED) && ((free_chunk->start * kMemoryAlign) & (pagesize - 1)),
+                "PAGE_ALIGNED requested, but page is not aligned!!!");
+
+            const ssize_t tail_free = free_size - (size + extra);
+            if (tail_free > 0) {
+                chunk_t* split = new chunk_t(free_chunk->start + free_chunk->size, tail_free);
+                mList.insert(++free_chunk_p, split);
+            }
+        }
+        return (free_chunk->start) * kMemoryAlign;
+    }
+    return NO_MEMORY;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start) {
+    start = start / kMemoryAlign;
+
+    for (Iterator pos = mList.begin(); pos != mList.end(); pos++) {
+        chunk_t* cur = *pos;
+        if (cur->start == start) {
+            LOG_FATAL_IF(cur->free, "block at offset 0x%08lX of size 0x%08lX already freed",
+                         cur->start * kMemoryAlign, cur->size * kMemoryAlign);
+
+            // merge freed blocks together
+            chunk_t* freed = cur;
+            cur->free = 1;
+            do {
+                if (pos != mList.begin()) {
+                    pos--;
+                    chunk_t* const p = *pos;
+                    pos++;
+                    if (p->free || !cur->size) {
+                        freed = p;
+                        p->size += cur->size;
+                        pos = mList.erase(pos);
+                        delete cur;
+                        if (pos == mList.end()) break;
+                    }
+                }
+                if (++pos == mList.end()) break;
+                cur = *pos;
+            } while (cur && cur->free);
+
+#ifndef NDEBUG
+            if (!freed->free) {
+                dump_l("dealloc (!freed->free)");
+            }
+#endif
+            LOG_FATAL_IF(!freed->free, "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                         freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+            return freed;
+        }
+    }
+    return nullptr;
+}
+
+void SimpleBestFitAllocator::dump(const char* tag) const {
+    Lock lock(mLock);
+    dump_l(tag);
+}
+
+void SimpleBestFitAllocator::dump_l(const char* tag) const {
+    string result;
+    dump_l(result, tag);
+    ALOGD("%s", result.c_str());
+}
+
+void SimpleBestFitAllocator::dump(string& result, const char* tag) const {
+    Lock lock(mLock);
+    dump_l(result, tag);
+}
+
+void SimpleBestFitAllocator::dump_l(string& result, const char* tag) const {
+    size_t size = 0;
+    int32_t i = 0;
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "  %s (%p, size=%u)\n", tag, this, (unsigned int)mHeapSize);
+
+    result.append(buffer);
+
+    for (IteratorConst pos = mList.begin(); pos != mList.end(); pos++) {
+        chunk_t const* cur = *pos;
+
+        if (!cur->free) size += cur->size * kMemoryAlign;
+
+        i++;
+    }
+    snprintf(buffer, SIZE, "  size allocated: %u (%u KB)\n", int(size), int(size / 1024));
+    result.append(buffer);
+}
+
+bool HidlMemoryDealer::isOk(const MemoryBlock& memblk) {
+    return memblk.token != nullptr;
+}
+
+sp<::android::hidl::memory::V1_0::IMemory> HidlMemoryDealer::heap() {
+    return mHeap;
+}
+
+// The required heap size alignment is 4096 bytes
+static const uint64_t kHeapSizeAlignment = (0x1ULL << 12);
+
+sp<HidlMemoryDealer> HidlMemoryDealer::getInstance(const hidl_memory& mem) {
+    uint64_t msk = (kHeapSizeAlignment - 1);
+    if (mem.size() & msk || !(mem.size() & ~msk)) {
+        ALOGE("size is not aligned to %x", static_cast<uint32_t>(kHeapSizeAlignment));
+        return nullptr;
+    }
+    sp<IMemory> heap = mapMemory(mem);
+    if (heap == nullptr) {
+        ALOGE("fail to mapMemory");
+        return nullptr;
+    }
+    return new HidlMemoryDealer(heap, mem);
+}
+
+HidlMemoryDealer::HidlMemoryDealer(sp<IMemory> heap, const hidl_memory& mem)
+    : MemoryDealer(heap->getSize()),
+      mHeap(heap),
+      mToken(new HidlMemoryToken(HidlMemory::getInstance(mem))) {}
+
+::android::hidl::memory::block::V1_0::MemoryBlock HidlMemoryDealer::allocate(size_t size) {
+    MemoryBlock memblk = {nullptr, 0xFFFFFFFFULL, 0xFFFFFFFFULL};
+    ssize_t offset = allocateOffset(size);
+    if (offset >= 0) {
+        memblk.token = mToken;
+        memblk.size = size;
+        memblk.offset = offset;
+    }
+    return memblk;
+}
+
+};  // namespace hardware
+};  // namespace android
diff --git a/libhidlcache/include/hidlcache/MemoryDealer.h b/libhidlcache/include/hidlcache/MemoryDealer.h
new file mode 100644
index 0000000..fceed83
--- /dev/null
+++ b/libhidlcache/include/hidlcache/MemoryDealer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 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_MEMORY_DEALER_H
+#define ANDROID_HIDL_MEMORY_DEALER_H
+
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/hidl/memory/block/1.0/types.h>
+#include <stdint.h>
+#include <sys/types.h>
+namespace android {
+namespace hardware {
+
+class SimpleBestFitAllocator;
+
+// MemoryDealer allocates/deallocates blocks from a continuous memory region.
+// It operates on size and offset and does not depend on any specific data types.
+class MemoryDealer : public RefBase {
+   public:
+    /// Allocate a block with size. The allocated block is identified with an
+    /// offset. For example:
+    /// ssize_t K = dealer->allocateOffset(size);
+    /// On success, K is positive and points to a subregion K ~ (K+size-1) in the heap.
+    /// It's negative if the allocation fails.
+    virtual ssize_t allocateOffset(size_t size);
+    /// @param offset It points to the block that allocated with allocateOffset previously.
+    virtual void deallocate(size_t offset);
+    /// @param tag a string tag used to mark the dump message
+    virtual void dump(const char* tag) const;
+
+    // allocations are aligned to some value. return that value so clients can account for it.
+    static size_t getAllocationAlignment();
+
+    MemoryDealer(size_t size);
+    virtual ~MemoryDealer();
+
+   protected:
+    SimpleBestFitAllocator* mAllocator;
+};
+
+// It extends the generic MemoryDealer and uses
+//  - sp<IMemory> to represent the main memory region.
+//  - MemoryBlock to represent the the block to allocate/deallocate
+class HidlMemoryDealer : public MemoryDealer {
+    using IMemory = ::android::hidl::memory::V1_0::IMemory;
+    using IMemoryToken = ::android::hidl::memory::token::V1_0::IMemoryToken;
+    using MemoryBlock = ::android::hidl::memory::block::V1_0::MemoryBlock;
+
+   public:
+    static bool isOk(const MemoryBlock& memblk);
+    /// @param memory The memory size must align to 4096 bytes
+    static sp<HidlMemoryDealer> getInstance(const hidl_memory& memory);
+    virtual MemoryBlock allocate(size_t size);
+    virtual sp<IMemory> heap();
+
+   protected:
+    /// @param heap It must be acquired with mapMemory(memory) with its
+    /// argument corresponds to the 2nd argument passed to HidlMemoryDealer.
+    HidlMemoryDealer(sp<IMemory> heap, const hidl_memory& memory);
+    sp<IMemory> mHeap;
+    sp<IMemoryToken> mToken;
+};
+
+};  // namespace hardware
+};  // namespace android
+
+#endif  // ANDROID_HIDL_MEMORY_DEALER_H
diff --git a/libhidlcache/include/hidlcache/mapping.h b/libhidlcache/include/hidlcache/mapping.h
new file mode 100644
index 0000000..972b7b5
--- /dev/null
+++ b/libhidlcache/include/hidlcache/mapping.h
@@ -0,0 +1,54 @@
+/*
+ * 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_HARDWARE_CACHE_MAPPING_H
+#define ANDROID_HARDWARE_CACHE_MAPPING_H
+
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/hidl/memory/block/1.0/types.h>
+#include <android/hidl/memory/token/1.0/IMemoryToken.h>
+
+namespace android {
+namespace hardware {
+
+/**
+ * Returns the IMemory instance corresponding to a MemoryBlock. The heap that
+ * a MemoryBlock belongs to is stored in an internal cache to reduce the number
+ * of invocations to the mapMemory(hidl_memory)
+ *
+ * Note, a cache entry is maintained by reference count and may be flushed when
+ * the count decrease to zero. Performance critical part that does not want its
+ * caches to be flushed can use HidlMemoryCacheLock.
+ */
+sp<::android::hidl::memory::V1_0::IMemory> mapMemory(
+    const ::android::hidl::memory::block::V1_0::MemoryBlock& block);
+
+/**
+ * Internally, there's a cache pool to keep IMemory instances for heap regions
+ * that are referred by the MemoryBlock. During development, this
+ * lockMemoryCache(...) method helps to diagnosis whether the cache is effective
+ * for a specific key. It returns a RAII object used to lock an IMemory instance
+ * referred by the key and keep it alive even if the instance is not referred by
+ * any MemoryBlock. If the cache in interest is already effective. It won't differ
+ * much in performance w/ wo/ the lockMemoryCache()
+ *
+ * @note An IMemory instance that is returned from the mapMemory() is
+ *       initialized in an unlocked state.
+ */
+sp<RefBase> lockMemoryCache(const sp<::android::hidl::memory::token::V1_0::IMemoryToken> key);
+
+}  // namespace hardware
+}  // namespace android
+#endif
diff --git a/libhidlcache/libhidlcache_test.cpp b/libhidlcache/libhidlcache_test.cpp
new file mode 100644
index 0000000..e514460
--- /dev/null
+++ b/libhidlcache/libhidlcache_test.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "hidl-cache-test"
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/hidl/memory/token/1.0/IMemoryToken.h>
+#include <gtest/gtest.h>
+#include <hidlcache/MemoryDealer.h>
+#include <hidlcache/mapping.h>
+#include <hidlmemory/HidlMemoryToken.h>
+#include <hidlmemory/mapping.h>
+#include "HidlMemoryCache.h"
+
+#define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
+
+template <typename T>
+static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
+    return ret.isOk() ? (::testing::AssertionSuccess() << ret.description())
+                      : (::testing::AssertionFailure() << ret.description());
+}
+
+namespace android {
+
+namespace hardware {
+void HidlCacheWhiteBoxTest() {
+    using ::android::hardware::HidlMemoryCache;
+    using ::android::hardware::HidlMemoryToken;
+    using ::android::hidl::allocator::V1_0::IAllocator;
+    using ::android::hidl::memory::V1_0::IMemory;
+    using ::android::hidl::memory::token::V1_0::IMemoryToken;
+    using ::android::hidl::memory::block::V1_0::MemoryBlock;
+
+    sp<IAllocator> ashmemAllocator;
+
+    ashmemAllocator = IAllocator::getService("ashmem");
+    ASSERT_NE(nullptr, ashmemAllocator.get());
+    ASSERT_TRUE(ashmemAllocator->isRemote());  // allocator is always remote
+
+    sp<HidlMemory> mem;
+    EXPECT_OK(ashmemAllocator->allocate(1024, [&](bool success, const hidl_memory& _mem) {
+        ASSERT_TRUE(success);
+        mem = HidlMemory::getInstance(_mem);
+    }));
+
+    sp<IMemoryToken> token = new HidlMemoryToken(mem);
+
+    MemoryBlock blk = {token, 0x200 /* size */, 0x100 /* offset */};
+    sp<IMemoryToken> mtoken = blk.token;
+    mtoken->get([&](const hidl_memory& mem) { sp<IMemory> memory = mapMemory(mem); });
+
+    sp<HidlMemoryCache> cache = HidlMemoryCache::getInstance();
+    EXPECT_FALSE(cache->cached(token));
+
+    MemoryBlock blk2 = {token, 0x200 /* size */, 0x300 /* offset */};
+
+    EXPECT_FALSE(cache->cached(token));
+
+    {
+        sp<IMemory> mem1 = cache->fetch(token);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+        sp<IMemory> mem2 = cache->fetch(token);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    }
+    EXPECT_FALSE(cache->cached(token));
+    {
+        sp<IMemory> mem1 = mapMemory(blk);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+        uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(mem1->getPointer()));
+        EXPECT_NE(nullptr, data);
+    }
+    {
+        sp<IMemory> mem2 = mapMemory(blk);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    }
+    EXPECT_FALSE(cache->cached(token));
+    EXPECT_TRUE(cache->lock(token));
+    EXPECT_TRUE(cache->cached(token));
+    EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    EXPECT_TRUE(cache->unlock(token));
+    EXPECT_FALSE(cache->cached(token));
+}
+}  // namespace hardware
+
+class HidlCacheTest : public ::testing::Test {};
+
+TEST_F(HidlCacheTest, TestAll) {
+    hardware::HidlCacheWhiteBoxTest();
+}
+
+TEST_F(HidlCacheTest, MemoryDealer) {
+    using ::android::hardware::HidlMemory;
+    using ::android::hardware::hidl_memory;
+    using ::android::hardware::HidlMemoryDealer;
+    using ::android::hidl::allocator::V1_0::IAllocator;
+    using ::android::hidl::memory::block::V1_0::MemoryBlock;
+
+    sp<IAllocator> ashmemAllocator;
+
+    ashmemAllocator = IAllocator::getService("ashmem");
+    sp<HidlMemory> m1;
+    sp<HidlMemory> m2;
+    // test MemoryDealer
+    EXPECT_OK(ashmemAllocator->allocate(2048, [&m1](bool success, const hidl_memory& mem) {
+        ASSERT_TRUE(success);
+        m1 = HidlMemory::getInstance(mem);
+    }));
+
+    EXPECT_OK(ashmemAllocator->allocate(4096, [&m2](bool success, const hidl_memory& mem) {
+        ASSERT_TRUE(success);
+        m2 = HidlMemory::getInstance(mem);
+    }));
+
+    sp<HidlMemoryDealer> dealer;
+
+    // m1 does not statisfy the alignment requirement and should fail.
+    dealer = HidlMemoryDealer::getInstance(*m1);
+    EXPECT_EQ(nullptr, dealer.get());
+
+    dealer = HidlMemoryDealer::getInstance(*m2);
+    EXPECT_NE(nullptr, dealer.get());
+
+    EXPECT_EQ(dealer->heap()->getSize(), 4096ULL);
+    MemoryBlock blk = dealer->allocate(1024);
+    EXPECT_TRUE(HidlMemoryDealer::isOk(blk));
+    MemoryBlock blk2 = dealer->allocate(2048);
+    EXPECT_TRUE(HidlMemoryDealer::isOk(blk2));
+
+    MemoryBlock blk3 = dealer->allocate(2048);
+    EXPECT_FALSE(HidlMemoryDealer::isOk(blk3));
+    dealer->deallocate(blk2.offset);
+    blk3 = dealer->allocate(2048);
+    EXPECT_TRUE(HidlMemoryDealer::isOk(blk3));
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/libhidlcache/mapping.cpp b/libhidlcache/mapping.cpp
new file mode 100644
index 0000000..2a23e6f
--- /dev/null
+++ b/libhidlcache/mapping.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "libhidlmemory"
+
+#include <map>
+#include <mutex>
+#include <string>
+
+#include <hidlmemory/mapping.h>
+
+#include <android-base/logging.h>
+#include <hidl/HidlSupport.h>
+#include "HidlMemoryCache.h"
+
+using android::hardware::HidlMemoryCache;
+using android::hidl::memory::block::V1_0::MemoryBlock;
+using android::hidl::memory::token::V1_0::IMemoryToken;
+using android::hidl::memory::V1_0::IMemory;
+
+namespace android {
+namespace hardware {
+
+sp<IMemory> mapMemory(const ::android::hidl::memory::block::V1_0::MemoryBlock& block) {
+    sp<HidlMemoryCache> c = HidlMemoryCache::getInstance();
+    return c->map(block);
+}
+
+sp<RefBase> lockMemoryCache(const sp<::android::hidl::memory::token::V1_0::IMemoryToken> key) {
+    sp<HidlMemoryCache> c = HidlMemoryCache::getInstance();
+    return c->lockGuard(key);
+}
+
+}  // namespace hardware
+}  // namespace android
diff --git a/libhidlmemory/Android.bp b/libhidlmemory/Android.bp
index 2f97d5d..2135ef3 100644
--- a/libhidlmemory/Android.bp
+++ b/libhidlmemory/Android.bp
@@ -26,6 +26,7 @@
         "libutils",
         "libcutils",
         "libhidlbase",
+        "libhidltransport",
         "android.hidl.memory@1.0",
         "android.hidl.memory.token@1.0",
     ],
diff --git a/test_main.cpp b/test_main.cpp
index e4cdd29..2b9f52c 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -16,16 +16,11 @@
 
 #define LOG_TAG "LibHidlTest"
 
-#pragma clang diagnostic push
-#pragma clang diagnostic fatal "-Wpadded"
-#include <hidl/HidlInternal.h>
-#include <hidl/HidlSupport.h>
-#pragma clang diagnostic pop
-
 #include <android-base/logging.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <hidl/HidlSupport.h>
 #include <hidl/ServiceManagement.h>
 #include <hidl/Status.h>
 #include <hidl/TaskRunner.h>
@@ -33,12 +28,6 @@
 #include <fstream>
 #include <vector>
 
-#ifdef __ANDROID__
-static bool kAndroid = true;
-#else
-static bool kAndroid = false;
-#endif
-
 #define EXPECT_ARRAYEQ(__a1__, __a2__, __size__) EXPECT_TRUE(isArrayEqual(__a1__, __a2__, __size__))
 #define EXPECT_2DARRAYEQ(__a1__, __a2__, __size1__, __size2__) \
         EXPECT_TRUE(is2dArrayEqual(__a1__, __a2__, __size1__, __size2__))
@@ -330,72 +319,6 @@
     EXPECT_EQ(sum, 1 + 2 + 3);
 }
 
-struct FailsIfCopied {
-    FailsIfCopied() {}
-
-    // add failure if copied since in general this can be expensive
-    FailsIfCopied(const FailsIfCopied& o) { *this = o; }
-    FailsIfCopied& operator=(const FailsIfCopied&) {
-        ADD_FAILURE() << "FailsIfCopied copied";
-        return *this;
-    }
-
-    // fine to move this type since in general this is cheaper
-    FailsIfCopied(FailsIfCopied&& o) = default;
-    FailsIfCopied& operator=(FailsIfCopied&&) = default;
-};
-
-TEST_F(LibHidlTest, VecResizeNoCopy) {
-    using android::hardware::hidl_vec;
-
-    hidl_vec<FailsIfCopied> noCopies;
-    noCopies.resize(3);  // instantiates three elements
-
-    FailsIfCopied* oldPointer = noCopies.data();
-
-    noCopies.resize(6);  // should move three elements, not copy
-
-    // oldPointer should be invalidated at this point.
-    // hidl_vec doesn't currently try to realloc but if it ever switches
-    // to an implementation that does, this test wouldn't do anything.
-    EXPECT_NE(oldPointer, noCopies.data());
-}
-
-TEST_F(LibHidlTest, VecFindTest) {
-    using android::hardware::hidl_vec;
-    hidl_vec<int32_t> hv1 = {10, 20, 30, 40};
-    const hidl_vec<int32_t> hv2 = {1, 2, 3, 4};
-
-    auto it = hv1.find(20);
-    EXPECT_EQ(20, *it);
-    *it = 21;
-    EXPECT_EQ(21, *it);
-    it = hv1.find(20);
-    EXPECT_EQ(hv1.end(), it);
-    it = hv1.find(21);
-    EXPECT_EQ(21, *it);
-
-    auto cit = hv2.find(4);
-    EXPECT_EQ(4, *cit);
-}
-
-TEST_F(LibHidlTest, VecContainsTest) {
-    using android::hardware::hidl_vec;
-    hidl_vec<int32_t> hv1 = {10, 20, 30, 40};
-    const hidl_vec<int32_t> hv2 = {0, 1, 2, 3, 4};
-
-    EXPECT_TRUE(hv1.contains(10));
-    EXPECT_TRUE(hv1.contains(40));
-    EXPECT_FALSE(hv1.contains(1));
-    EXPECT_FALSE(hv1.contains(0));
-    EXPECT_TRUE(hv2.contains(0));
-    EXPECT_FALSE(hv2.contains(10));
-
-    hv1[0] = 11;
-    EXPECT_FALSE(hv1.contains(10));
-    EXPECT_TRUE(hv1.contains(11));
-}
-
 TEST_F(LibHidlTest, ArrayTest) {
     using android::hardware::hidl_array;
     int32_t array[] = {5, 6, 7};
@@ -530,52 +453,6 @@
     EXPECT_EQ(three, ret.withDefault(three));
 }
 
-TEST_F(LibHidlTest, ReturnDies) {
-    using ::android::hardware::Return;
-    using ::android::hardware::Status;
-
-    EXPECT_DEATH({ Return<void>(Status::fromStatusT(-EBUSY)); }, "");
-    EXPECT_DEATH({ Return<void>(Status::fromStatusT(-EBUSY)).isDeadObject(); }, "");
-    EXPECT_DEATH(
-            {
-                Return<int> ret = Return<int>(Status::fromStatusT(-EBUSY));
-                int foo = ret;  // should crash here
-                (void)foo;
-                ret.isOk();
-            },
-            "");
-}
-
-TEST_F(LibHidlTest, DetectUncheckedReturn) {
-    using ::android::hardware::HidlReturnRestriction;
-    using ::android::hardware::Return;
-    using ::android::hardware::setProcessHidlReturnRestriction;
-    using ::android::hardware::Status;
-
-    setProcessHidlReturnRestriction(HidlReturnRestriction::FATAL_IF_UNCHECKED);
-
-    EXPECT_DEATH(
-            {
-                auto ret = Return<void>(Status::ok());
-                (void)ret;
-            },
-            "");
-    EXPECT_DEATH(
-            {
-                auto ret = Return<void>(Status::ok());
-                ret = Return<void>(Status::ok());
-                ret.isOk();
-            },
-            "");
-
-    auto ret = Return<void>(Status::ok());
-    (void)ret.isOk();
-    ret = Return<void>(Status::ok());
-    (void)ret.isOk();
-
-    setProcessHidlReturnRestriction(HidlReturnRestriction::NONE);
-}
-
 std::string toString(const ::android::hardware::Status &s) {
     using ::android::hardware::operator<<;
     std::ostringstream oss;
@@ -599,10 +476,6 @@
 }
 
 TEST_F(LibHidlTest, PreloadTest) {
-    // HIDL doesn't have support to load passthrough implementations on host, but we
-    // could do this by loading implementations from the output directory
-    if (!kAndroid) GTEST_SKIP();
-
     using ::android::hardware::preloadPassthroughService;
     using ::android::hidl::memory::V1_0::IMemory;
 
@@ -615,51 +488,6 @@
     EXPECT_TRUE(isLibraryOpen(kLib));
 }
 
-template <typename T, size_t start, size_t end>
-static void assertZeroInRange(const T* t) {
-    static_assert(start < sizeof(T));
-    static_assert(end <= sizeof(T));
-
-    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(t);
-
-    for (size_t i = start; i < end; i++) {
-        EXPECT_EQ(0, ptr[i]);
-    }
-}
-
-template <typename T, size_t start, size_t end>
-static void uninitTest() {
-    uint8_t buf[sizeof(T)];
-    memset(buf, 0xFF, sizeof(T));
-
-    T* type = new (buf) T;
-    assertZeroInRange<T, start, end>(type);
-    type->~T();
-}
-
-TEST_F(LibHidlTest, HidlVecUninit) {
-    using ::android::hardware::hidl_vec;
-    struct SomeType {};
-    static_assert(sizeof(hidl_vec<SomeType>) == 16);
-
-    // padding after mOwnsBuffer
-    uninitTest<hidl_vec<SomeType>, 13, 16>();
-}
-TEST_F(LibHidlTest, HidlHandleUninit) {
-    using ::android::hardware::hidl_handle;
-    static_assert(sizeof(hidl_handle) == 16);
-
-    // padding after mOwnsHandle
-    uninitTest<hidl_handle, 9, 16>();
-}
-TEST_F(LibHidlTest, HidlStringUninit) {
-    using ::android::hardware::hidl_string;
-    static_assert(sizeof(hidl_string) == 16);
-
-    // padding after mOwnsBuffer
-    uninitTest<hidl_string, 13, 16>();
-}
-
 int main(int argc, char **argv) {
     ::testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
diff --git a/transport/Android.bp b/transport/Android.bp
index 324dbde..50f277e 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -22,32 +22,23 @@
         "libbase",
         "liblog",
         "libutils",
+        "libhwbinder",
         "libcutils",
+        "libvndksupport"
     ],
     export_shared_lib_headers: [
         "libutils",
     ],
-    static_libs: [
-        "libhwbinder-impl-internal",
-    ],
 
     target: {
-        android: {
-            shared_libs: [
-                "libvndksupport",
-            ],
-        },
         recovery: {
-            exclude_shared_libs: [
-                "libvndksupport",
-            ],
+            exclude_shared_libs: ["libvndksupport"],
         },
     },
 }
 
 cc_library_static {
     name: "libhidltransport-impl-internal",
-    host_supported: true,
     vendor_available: true,
     recovery_available: true,
 
@@ -103,6 +94,4 @@
             cflags: ["-DENFORCE_VINTF_MANIFEST"]
         },
     },
-
-    visibility: ["//system/libhidl:__subpackages__"],
 }
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index 02d10d0..352ed78 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -163,6 +163,20 @@
             parentOffset + hidl_string::kOffsetOfBuffer);
 }
 
+android::status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel) {
+    return parcel.writeUint32(static_cast<uint32_t>(version.get_major()) << 16 | version.get_minor());
+}
+
+hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
+    uint32_t version;
+    android::status_t status = parcel.readUint32(&version);
+    if (status != OK) {
+        return nullptr;
+    } else {
+        return new hidl_version(version >> 16, version & 0xFFFF);
+    }
+}
+
 status_t readFromParcel(Status *s, const Parcel& parcel) {
     int32_t exception;
     status_t status = parcel.readInt32(&exception);
diff --git a/transport/HidlLazyUtils.cpp b/transport/HidlLazyUtils.cpp
index 08ed676..8e3fdf3 100644
--- a/transport/HidlLazyUtils.cpp
+++ b/transport/HidlLazyUtils.cpp
@@ -181,11 +181,6 @@
     mImpl = std::make_shared<details::LazyServiceRegistrarImpl>();
 }
 
-LazyServiceRegistrar& LazyServiceRegistrar::getInstance() {
-    static auto registrarInstance = new LazyServiceRegistrar();
-    return *registrarInstance;
-}
-
 status_t LazyServiceRegistrar::registerService(
     const sp<::android::hidl::base::V1_0::IBase>& service, const std::string& name) {
     return mImpl->registerService(service, name);
diff --git a/transport/HidlTransportSupport.cpp b/transport/HidlTransportSupport.cpp
index e645cd0..b433b70 100644
--- a/transport/HidlTransportSupport.cpp
+++ b/transport/HidlTransportSupport.cpp
@@ -13,16 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <hidl/HidlTransportSupport.h>
-
 #include <hidl/HidlBinderSupport.h>
-#include "InternalStatic.h"
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Static.h>
 
 #include <android-base/logging.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 
-#include <linux/sched.h>
-
 namespace android {
 namespace hardware {
 
@@ -95,10 +92,6 @@
     return true;
 }
 
-SchedPrio getMinSchedulerPolicy(const sp<IBase>& service) {
-    return details::gServicePrioMap->get(service, {SCHED_NORMAL, 0});
-}
-
 bool setRequestingSid(const sp<IBase>& service, bool requesting) {
     if (service->isRemote()) {
         LOG(ERROR) << "Can't set requesting sid on remote service.";
@@ -115,10 +108,6 @@
     return true;
 }
 
-bool getRequestingSid(const sp<IBase>& service) {
-    return details::gServiceSidMap->get(service.get(), false);
-}
-
 bool interfacesEqual(const sp<IBase>& left, const sp<IBase>& right) {
     if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
         return left == right;
diff --git a/transport/InternalStatic.h b/transport/InternalStatic.h
index 666b2b6..1dfaae4 100644
--- a/transport/InternalStatic.h
+++ b/transport/InternalStatic.h
@@ -20,26 +20,19 @@
 #ifndef ANDROID_HARDWARE_HIDL_INTERNAL_STATIC_H
 #define ANDROID_HARDWARE_HIDL_INTERNAL_STATIC_H
 
-#include <hidl/HidlTransportSupport.h>  // for SchedPrio
 #include <hidl/Static.h>
 
 namespace android {
 namespace hardware {
 namespace details {
 
-// TODO(b/69122224): remove this once no prebuilts reference it
+// TODO(b/69122224): remove this
 // deprecated; use getBnConstructorMap instead.
 extern DoNotDestruct<BnConstructorMap> gBnConstructorMap;
-// TODO(b/69122224): remove this once no prebuilts reference it
+// TODO(b/69122224): remove this
 // deprecated; use getBsConstructorMap instead.
 extern DoNotDestruct<BsConstructorMap> gBsConstructorMap;
 
-// TODO(b/69122224): remove this once no prebuilts reference it
-extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio>>
-        gServicePrioMap;
-// TODO(b/69122224): remove this once no prebuilts reference it
-extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool>> gServiceSidMap;
-
 }  // namespace details
 }  // namespace hardware
 }  // namespace android
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 19d1d52..e7bec41 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "HidlServiceManagement"
+#define LOG_TAG "ServiceManagement"
 
-#ifdef __ANDROID__
 #include <android/dlext.h>
-#endif  // __ANDROID__
-
 #include <condition_variable>
 #include <dlfcn.h>
 #include <dirent.h>
@@ -46,7 +43,7 @@
 #include <android-base/strings.h>
 #include <hwbinder/IPCThreadState.h>
 #include <hwbinder/Parcel.h>
-#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
+#if !defined(__ANDROID_RECOVERY__)
 #include <vndksupport/linker.h>
 #endif
 
@@ -58,6 +55,8 @@
 #define RE_PATH         RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
 static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so");
 
+using android::base::WaitForProperty;
+
 using ::android::hidl::base::V1_0::IBase;
 using IServiceManager1_0 = android::hidl::manager::V1_0::IServiceManager;
 using IServiceManager1_1 = android::hidl::manager::V1_1::IServiceManager;
@@ -67,6 +66,8 @@
 namespace android {
 namespace hardware {
 
+static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready";
+
 #if defined(__ANDROID_RECOVERY__)
 static constexpr bool kIsRecovery = true;
 #else
@@ -74,18 +75,11 @@
 #endif
 
 static void waitForHwServiceManager() {
-    // TODO(b/31559095): need bionic host so that we can use 'prop_info' returned
-    // from WaitForProperty
-#ifdef __ANDROID__
-    static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready";
-
     using std::literals::chrono_literals::operator""s;
 
-    using android::base::WaitForProperty;
     while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) {
         LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another...";
     }
-#endif  // __ANDROID__
 }
 
 static std::string binaryName() {
@@ -382,6 +376,13 @@
             } else if (!eachLib(handle, "SELF", sym)) {
                 return;
             }
+
+            const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
+            if (vtsRootPath && strlen(vtsRootPath) > 0) {
+                const std::string halLibraryPathVtsOverride =
+                    std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
+                paths.insert(paths.begin(), halLibraryPathVtsOverride);
+            }
         }
 #endif
 
@@ -394,7 +395,7 @@
                 if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
                     handle = dlopen(fullPath.c_str(), dlMode);
                 } else {
-#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
+#if !defined(__ANDROID_RECOVERY__)
                     handle = android_load_sphal_library(fullPath.c_str(), dlMode);
 #endif
                 }
@@ -558,18 +559,6 @@
     return manager;
 }
 
-std::vector<std::string> getAllHalInstanceNames(const std::string& descriptor) {
-    std::vector<std::string> ret;
-    auto sm = defaultServiceManager1_2();
-    sm->listManifestByInterface(descriptor, [&](const auto& instances) {
-        ret.reserve(instances.size());
-        for (const auto& i : instances) {
-            ret.push_back(i);
-        }
-    });
-    return ret;
-}
-
 namespace details {
 
 void preloadPassthroughService(const std::string &descriptor) {
@@ -734,32 +723,11 @@
     return false;
 }
 
-#ifdef ENFORCE_VINTF_MANIFEST
-static constexpr bool kEnforceVintfManifest = true;
-#else
-static constexpr bool kEnforceVintfManifest = false;
-#endif
-
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
-static constexpr bool kDebuggable = true;
-#else
-static constexpr bool kDebuggable = false;
-#endif
-
-static inline bool isTrebleTestingOverride() {
-    if (kEnforceVintfManifest && !kDebuggable) {
-        // don't allow testing override in production
-        return false;
-    }
-
-    const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
-    return env && !strcmp(env, "true");
-}
-
 sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                              const std::string& instance,
                                                              bool retry, bool getStub) {
-    using Transport = IServiceManager1_0::Transport;
+    using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
+    using ::android::hidl::manager::V1_0::IServiceManager;
     sp<Waiter> waiter;
 
     sp<IServiceManager1_1> sm;
@@ -785,19 +753,23 @@
 
     const bool vintfHwbinder = (transport == Transport::HWBINDER);
     const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
-    const bool trebleTestingOverride = isTrebleTestingOverride();
-    const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && kDebuggable);
-    const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;
 
-    if (!kEnforceVintfManifest) {
-        ALOGE("getService: Potential race detected. The VINTF manifest is not being enforced. If "
-              "a HAL server has a delay in starting and it is not in the manifest, it will not be "
-              "retrieved. Please make sure all HALs on this device are in the VINTF manifest and "
-              "enable PRODUCT_ENFORCE_VINTF_MANIFEST on this device (this is also enabled by "
-              "PRODUCT_FULL_TREBLE). PRODUCT_ENFORCE_VINTF_MANIFEST will ensure that no race "
-              "condition is possible here.");
-        sleep(1);
-    }
+#ifdef ENFORCE_VINTF_MANIFEST
+
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
+    const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
+    const bool trebleTestingOverride = env && !strcmp(env, "true");
+    const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
+#else   // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
+    const bool trebleTestingOverride = false;
+    const bool vintfLegacy = false;
+#endif  // LIBHIDL_TARGET_DEBUGGABLE
+
+#else   // not ENFORCE_VINTF_MANIFEST
+    const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
+    const bool trebleTestingOverride = env && !strcmp(env, "true");
+    const bool vintfLegacy = (transport == Transport::EMPTY);
+#endif  // ENFORCE_VINTF_MANIFEST
 
     for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
         if (waiter == nullptr && tries > 0) {
@@ -841,7 +813,7 @@
     }
 
     if (getStub || vintfPassthru || vintfLegacy) {
-        const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
+        const sp<IServiceManager> pm = getPassthroughServiceManager();
         if (pm != nullptr) {
             sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
             if (!getStub || trebleTestingOverride) {
@@ -864,19 +836,6 @@
         return INVALID_OPERATION;
     }
 
-    const std::string descriptor = getDescriptor(service.get());
-
-    if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
-        using Transport = IServiceManager1_0::Transport;
-        Transport transport = sm->getTransport(descriptor, name);
-
-        if (transport != Transport::HWBINDER) {
-            LOG(ERROR) << "Service " << descriptor << "/" << name
-                       << " must be in VINTF manifest in order to register/get.";
-            return UNKNOWN_ERROR;
-        }
-    }
-
     bool registered = false;
     Return<void> ret = service->interfaceChain([&](const auto& chain) {
         registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false);
@@ -887,7 +846,7 @@
     }
 
     if (registered) {
-        onRegistrationImpl(descriptor, name);
+        onRegistrationImpl(getDescriptor(service.get()), name);
     }
 
     return registered ? OK : UNKNOWN_ERROR;
diff --git a/transport/allocator/1.0/Android.bp b/transport/allocator/1.0/Android.bp
index 80364a7..a3d885a 100644
--- a/transport/allocator/1.0/Android.bp
+++ b/transport/allocator/1.0/Android.bp
@@ -14,3 +14,4 @@
     ],
     gen_java: false,
 }
+
diff --git a/transport/allocator/1.0/default/Android.bp b/transport/allocator/1.0/default/Android.bp
index 1116f1d..1fdfb26 100644
--- a/transport/allocator/1.0/default/Android.bp
+++ b/transport/allocator/1.0/default/Android.bp
@@ -26,6 +26,8 @@
     shared_libs: [
         "android.hidl.allocator@1.0",
         "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
         "libbase",
         "liblog",
         "libutils",
diff --git a/transport/allocator/1.0/utils/Android.bp b/transport/allocator/1.0/utils/Android.bp
index b324ef1..9f70963 100644
--- a/transport/allocator/1.0/utils/Android.bp
+++ b/transport/allocator/1.0/utils/Android.bp
@@ -24,6 +24,7 @@
         "libbinder",
         "libcutils",
         "libhidlbase",
+        "libhidltransport",
         "android.hidl.memory@1.0"
     ],
     export_include_dirs: ["include"],
diff --git a/transport/base/1.0/Android.bp b/transport/base/1.0/Android.bp
index f90831e..cebb01b 100644
--- a/transport/base/1.0/Android.bp
+++ b/transport/base/1.0/Android.bp
@@ -12,3 +12,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/base/1.0/vts/functional/Android.bp b/transport/base/1.0/vts/functional/Android.bp
index 38b03f7..f0bd45c 100644
--- a/transport/base/1.0/vts/functional/Android.bp
+++ b/transport/base/1.0/vts/functional/Android.bp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+
 cc_test {
     name: "vts_ibase_test",
     srcs: [
@@ -24,12 +25,10 @@
     shared_libs: [
         "libbase",
         "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
         "liblog",
         "libutils",
-        "libprotobuf-cpp-lite",
-        "libhidl-gen-utils",
-    ],
-    static_libs: [
-        "libinit_test_utils",
     ],
 }
+
diff --git a/transport/base/1.0/vts/functional/vts_ibase_test.cpp b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
index b77b2ad..6d66042 100644
--- a/transport/base/1.0/vts/functional/vts_ibase_test.cpp
+++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
@@ -13,32 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "vts_ibase_test"
 
-#include <algorithm>
 #include <functional>
 #include <map>
-#include <mutex>
 #include <string>
-#include <thread>
-#include <vector>
 
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
 #include <android/hidl/base/1.0/IBase.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <gtest/gtest.h>
-#include <hidl-util/FqInstance.h>
 #include <hidl/HidlBinderSupport.h>
 #include <hidl/ServiceManagement.h>
-#include <init-test-utils/service_utils.h>
 
-using android::FqInstance;
-using android::FQName;
-using android::sp;
-using android::wp;
-using android::base::Result;
 using android::hardware::hidl_array;
 using android::hardware::hidl_death_recipient;
 using android::hardware::hidl_handle;
@@ -48,8 +33,8 @@
 using android::hardware::toBinder;
 using android::hidl::base::V1_0::IBase;
 using android::hidl::manager::V1_0::IServiceManager;
-using android::init::ServiceInterfacesMap;
-using PidInterfacesMap = std::map<pid_t, std::set<FqInstance>>;
+using android::sp;
+using android::wp;
 
 template <typename T>
 static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
@@ -62,40 +47,8 @@
 struct Hal {
     sp<IBase> service;
     std::string name;  // space separated list of android.hidl.foo@1.0::IFoo/instance-name
-    FqInstance fq_instance;
 };
 
-template <typename T>
-std::string FqInstancesToString(const T& instances) {
-    std::set<std::string> instance_strings;
-    for (const FqInstance& instance : instances) {
-        instance_strings.insert(instance.string());
-    }
-    return android::base::Join(instance_strings, "\n");
-}
-
-pid_t GetServiceDebugPid(const std::string& service) {
-    return android::base::GetIntProperty("init.svc_debug_pid." + service, 0);
-}
-
-std::map<std::string, std::vector<Hal>> gDeclaredServiceHalMap;
-std::mutex gDeclaredServiceHalMapMutex;
-
-void GetHal(const std::string& service, const FqInstance& instance) {
-    if (instance.getFqName() == android::gIBaseFqName) {
-        return;
-    }
-
-    sp<IBase> hal = android::hardware::details::getRawServiceInternal(
-            instance.getFqName().string(), instance.getInstance(), true /*retry*/,
-            false /*getStub*/);
-    // Add to gDeclaredServiceHalMap if getRawServiceInternal() returns (even if
-    // the returned HAL is null). getRawServiceInternal() won't return if the
-    // HAL is in the VINTF but unable to start.
-    std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
-    gDeclaredServiceHalMap[service].push_back(Hal{.service = hal, .fq_instance = instance});
-}
-
 class VtsHalBaseV1_0TargetTest : public ::testing::Test {
    public:
     virtual void SetUp() override {
@@ -133,7 +86,7 @@
                     // include all the names this is registered as for error messages
                     iter->second.name += " " + strName;
                 } else {
-                    all_hals_.insert(iter, {binder, Hal{.service = service, .name = strName}});
+                    all_hals_.insert(iter, {binder, Hal{service, strName}});
                 }
             }
         }));
@@ -147,25 +100,6 @@
         }
     }
 
-    PidInterfacesMap GetPidInterfacesMap() {
-        PidInterfacesMap result;
-        EXPECT_OK(default_manager_->debugDump([&result](const auto& list) {
-            for (const auto& debug_info : list) {
-                if (debug_info.pid != static_cast<int32_t>(IServiceManager::PidConstant::NO_PID)) {
-                    FQName fqName;
-                    ASSERT_TRUE(fqName.setTo(debug_info.interfaceName.c_str()))
-                            << "Unable to parse interface: '" << debug_info.interfaceName.c_str();
-                    FqInstance fqInstance;
-                    ASSERT_TRUE(fqInstance.setTo(fqName, debug_info.instanceName.c_str()));
-                    if (fqInstance.getFqName() != android::gIBaseFqName) {
-                        result[debug_info.pid].insert(fqInstance);
-                    }
-                }
-            }
-        }));
-        return result;
-    }
-
     // default service manager
     sp<IServiceManager> default_manager_;
 
@@ -231,76 +165,6 @@
     });
 }
 
-TEST_F(VtsHalBaseV1_0TargetTest, ServiceProvidesAndDeclaresTheSameInterfaces) {
-    Result<ServiceInterfacesMap> service_interfaces_map =
-            android::init::GetOnDeviceServiceInterfacesMap();
-    ASSERT_TRUE(service_interfaces_map) << service_interfaces_map.error();
-
-    // Attempt to get handles to all known declared interfaces. This will cause
-    // any non-running lazy HALs to start up.
-    // Results are saved in gDeclaredServiceHalMap.
-    for (const auto& [service, declared_interfaces] : *service_interfaces_map) {
-        if (declared_interfaces.empty()) {
-            LOG(INFO) << "Service '" << service << "' does not declare any interfaces.";
-        }
-        for (const auto& instance : declared_interfaces) {
-            std::thread(GetHal, service, instance).detach();
-        }
-    }
-    // Allow the threads 5 seconds to attempt to get each HAL. Any HAL whose
-    // thread is stuck during retrieval is excluded from this test.
-    sleep(5);
-
-    std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
-    PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap();
-
-    // For each service that had at least one thread return from attempting to
-    // retrieve a HAL:
-    for (const auto& [service, hals] : gDeclaredServiceHalMap) {
-        // Assert that the service is running.
-        pid_t pid = GetServiceDebugPid(service);
-        ASSERT_NE(pid, 0) << "Service '" << service << "' is not running.";
-
-        std::set<FqInstance> declared_interfaces;
-        for (const auto& hal : hals) {
-            declared_interfaces.insert(hal.fq_instance);
-        }
-
-        // Warn for any threads that were stuck when attempting to retrieve a
-        // HAL.
-        std::vector<FqInstance> missing_declared_interfaces;
-        std::set_difference((*service_interfaces_map)[service].begin(),
-                            (*service_interfaces_map)[service].end(), declared_interfaces.begin(),
-                            declared_interfaces.end(),
-                            std::back_inserter(missing_declared_interfaces));
-        if (!missing_declared_interfaces.empty()) {
-            LOG(WARNING)
-                    << "Service '" << service
-                    << "' declares interfaces that are present in the VINTF but unable to start:"
-                    << std::endl
-                    << FqInstancesToString(missing_declared_interfaces);
-        }
-
-        // Expect that the set of interfaces running at this PID is the same as
-        // the set of interfaces declared by this service.
-        std::set<FqInstance> served_interfaces = pid_interfaces_map[pid];
-        std::vector<FqInstance> served_declared_diff;
-        std::set_symmetric_difference(declared_interfaces.begin(), declared_interfaces.end(),
-                                      served_interfaces.begin(), served_interfaces.end(),
-                                      std::back_inserter(served_declared_diff));
-
-        EXPECT_TRUE(served_declared_diff.empty())
-                << "Service '" << service << "' serves and declares different interfaces."
-                << std::endl
-                << "  Served:" << std::endl
-                << FqInstancesToString(served_interfaces) << std::endl
-                << "  Declared: " << std::endl
-                << FqInstancesToString(declared_interfaces) << std::endl
-                << "  Difference: " << std::endl
-                << FqInstancesToString(served_declared_diff);
-    }
-}
-
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index 5dec5cd..a098805 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -28,7 +28,7 @@
 #include <hwbinder/Parcel.h>
 #include <log/log.h>  // TODO(b/65843592): remove. Too many users depending on this transitively.
 
-// Defines functions for hidl_string, Status, hidl_vec, MQDescriptor,
+// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor,
 // etc. to interact with Parcel.
 
 namespace android {
@@ -72,6 +72,13 @@
 status_t writeEmbeddedToParcel(const hidl_string &string,
         Parcel *parcel, size_t parentHandle, size_t parentOffset);
 
+// ---------------------- hidl_version
+
+status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel);
+
+// Caller is responsible for freeing the returned object.
+hidl_version* readFromParcel(const android::hardware::Parcel& parcel);
+
 // ---------------------- Status
 
 // Bear in mind that if the client or service is a Java endpoint, this
@@ -178,6 +185,127 @@
     return _hidl_err;
 }
 
+// ---------------------- pointers for HIDL
+
+template <typename T>
+static status_t readEmbeddedReferenceFromParcel(
+        T const* * /* bufptr */,
+        const Parcel & parcel,
+        size_t parentHandle,
+        size_t parentOffset,
+        size_t *handle,
+        bool *shouldResolveRefInBuffer
+    ) {
+    // *bufptr is ignored because, if I am embedded in some
+    // other buffer, the kernel should have fixed me up already.
+    bool isPreviouslyWritten;
+    status_t result = parcel.readEmbeddedReference(
+        nullptr, // ignored, not written to bufptr.
+        handle,
+        parentHandle,
+        parentOffset,
+        &isPreviouslyWritten);
+    // tell caller to run T::readEmbeddedToParcel and
+    // T::readEmbeddedReferenceToParcel if necessary.
+    // It is not called here because we don't know if these two are valid methods.
+    *shouldResolveRefInBuffer = !isPreviouslyWritten;
+    return result;
+}
+
+template <typename T>
+static status_t writeEmbeddedReferenceToParcel(
+        T const* buf,
+        Parcel *parcel, size_t parentHandle, size_t parentOffset,
+        size_t *handle,
+        bool *shouldResolveRefInBuffer
+        ) {
+
+    if(buf == nullptr) {
+        *shouldResolveRefInBuffer = false;
+        return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
+    }
+
+    // find whether the buffer exists
+    size_t childHandle, childOffset;
+    status_t result;
+    bool found;
+
+    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
+
+    // tell caller to run T::writeEmbeddedToParcel and
+    // T::writeEmbeddedReferenceToParcel if necessary.
+    // It is not called here because we don't know if these two are valid methods.
+    *shouldResolveRefInBuffer = !found;
+
+    if(result != OK) {
+        return result; // bad pointers and length given
+    }
+    if(!found) { // did not find it.
+        return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
+                parentHandle, parentOffset);
+    }
+    // found the buffer. easy case.
+    return parcel->writeEmbeddedReference(
+            handle,
+            childHandle,
+            childOffset,
+            parentHandle,
+            parentOffset);
+}
+
+template <typename T>
+static status_t readReferenceFromParcel(
+        T const* *bufptr,
+        const Parcel & parcel,
+        size_t *handle,
+        bool *shouldResolveRefInBuffer
+    ) {
+    bool isPreviouslyWritten;
+    status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
+            handle, &isPreviouslyWritten);
+    // tell caller to run T::readEmbeddedToParcel and
+    // T::readEmbeddedReferenceToParcel if necessary.
+    // It is not called here because we don't know if these two are valid methods.
+    *shouldResolveRefInBuffer = !isPreviouslyWritten;
+    return result;
+}
+
+template <typename T>
+static status_t writeReferenceToParcel(
+        T const *buf,
+        Parcel * parcel,
+        size_t *handle,
+        bool *shouldResolveRefInBuffer
+    ) {
+
+    if(buf == nullptr) {
+        *shouldResolveRefInBuffer = false;
+        return parcel->writeNullReference(handle);
+    }
+
+    // find whether the buffer exists
+    size_t childHandle, childOffset;
+    status_t result;
+    bool found;
+
+    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
+
+    // tell caller to run T::writeEmbeddedToParcel and
+    // T::writeEmbeddedReferenceToParcel if necessary.
+    // It is not called here because we don't know if these two are valid methods.
+    *shouldResolveRefInBuffer = !found;
+
+    if(result != OK) {
+        return result; // bad pointers and length given
+    }
+    if(!found) { // did not find it.
+        return parcel->writeBuffer(buf, sizeof(T), handle);
+    }
+    // found the buffer. easy case.
+    return parcel->writeReference(handle,
+        childHandle, childOffset);
+}
+
 // ---------------------- support for casting interfaces
 
 // Constructs a binder for this interface and caches it. If it has already been created
diff --git a/transport/include/hidl/HidlLazyUtils.h b/transport/include/hidl/HidlLazyUtils.h
index 257de98..2205daa 100644
--- a/transport/include/hidl/HidlLazyUtils.h
+++ b/transport/include/hidl/HidlLazyUtils.h
@@ -29,13 +29,12 @@
 /** Exits when all HALs registered through this object have 0 clients */
 class LazyServiceRegistrar {
    public:
-     LazyServiceRegistrar();
-     static LazyServiceRegistrar& getInstance();
-     status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
-                              const std::string& name = "default");
+    LazyServiceRegistrar();
+    status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
+                             const std::string& name = "default");
 
    private:
-     std::shared_ptr<details::LazyServiceRegistrarImpl> mImpl;
+    std::shared_ptr<details::LazyServiceRegistrarImpl> mImpl;
 };
 
 }  // namespace hardware
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
index 454a4e5..a132bfa 100644
--- a/transport/include/hidl/HidlTransportSupport.h
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -84,13 +84,6 @@
 bool setMinSchedulerPolicy(const sp<::android::hidl::base::V1_0::IBase>& service,
                            int policy, int priority);
 
-struct SchedPrio {
-    int sched_policy;
-    int prio;
-};
-
-SchedPrio getMinSchedulerPolicy(const sp<::android::hidl::base::V1_0::IBase>& service);
-
 /**
  * Sets whether or not this object should request security contexts to be populatd for incoming
  * calls (e.g. with getCallingSid).
@@ -104,12 +97,6 @@
 bool setRequestingSid(const sp<::android::hidl::base::V1_0::IBase>& service, bool requesting);
 
 /**
- * Says whether or not this service is requesting a SID. If this was set after the service was
- * sent to another process, then it will not take effect.
- */
-bool getRequestingSid(const sp<::android::hidl::base::V1_0::IBase>& service);
-
-/**
  * Returns whether two interfaces represent the same interface. References to interfaces in the same
  * process will always be equivalent. However, in order to compare a service that is a proxy to a
  * different process, its underlying structure may have to be checked.
diff --git a/transport/include/hidl/LegacySupport.h b/transport/include/hidl/LegacySupport.h
index 7cb72a9..1e983eb 100644
--- a/transport/include/hidl/LegacySupport.h
+++ b/transport/include/hidl/LegacySupport.h
@@ -26,12 +26,9 @@
 namespace android {
 namespace hardware {
 namespace details {
-template <typename Interface>
-using RegisterServiceCb = std::function<status_t(const sp<Interface>&, const std::string&)>;
-
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface, typename Func>
 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
-        RegisterServiceCb<Interface> registerServiceCb, const std::string& name = "default") {
+    Func registerServiceCb, const std::string& name = "default") {
     sp<Interface> service = Interface::getService(name, true /* getStub */);
 
     if (service == nullptr) {
@@ -43,10 +40,6 @@
     LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
             Interface::descriptor, name.c_str());
 
-    sp<ExpectInterface> expected = ExpectInterface::castFrom(service);
-    LOG_FATAL_IF(expected == nullptr, "Implementation of %s/%s is not a %s!", Interface::descriptor,
-                 name.c_str(), ExpectInterface::descriptor);
-
     status_t status = registerServiceCb(service, name);
 
     if (status == OK) {
@@ -64,14 +57,14 @@
 /**
  * Registers passthrough service implementation.
  */
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface>
 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
-        const std::string& name = "default") {
-    return details::registerPassthroughServiceImplementation<Interface, ExpectInterface>(
-            [](const sp<Interface>& service, const std::string& name) {
-                return service->registerAsService(name);
-            },
-            name);
+    const std::string& name = "default") {
+    return details::registerPassthroughServiceImplementation<Interface>(
+        [](const sp<Interface>& service, const std::string& name) {
+            return service->registerAsService(name);
+        },
+        name);
 }
 
 /**
@@ -79,11 +72,11 @@
  *
  * Return value is exit status.
  */
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface>
 __attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
-        const std::string& name, size_t maxThreads = 1) {
+    const std::string& name, size_t maxThreads = 1) {
     configureRpcThreadpool(maxThreads, true);
-    status_t result = registerPassthroughServiceImplementation<Interface, ExpectInterface>(name);
+    status_t result = registerPassthroughServiceImplementation<Interface>(name);
 
     if (result != OK) {
         return result;
@@ -92,11 +85,10 @@
     joinRpcThreadpool();
     return UNKNOWN_ERROR;
 }
-template <class Interface, class ExpectInterface = Interface>
-__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
-        size_t maxThreads = 1) {
-    return defaultPassthroughServiceImplementation<Interface, ExpectInterface>("default",
-                                                                               maxThreads);
+template<class Interface>
+__attribute__((warn_unused_result))
+status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) {
+    return defaultPassthroughServiceImplementation<Interface>("default", maxThreads);
 }
 
 /**
@@ -107,15 +99,20 @@
  * through registerPassthroughServiceImplementation, so if that function is used in conjunction with
  * this one, the process may exit while a client is still using the HAL.
  */
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface>
 __attribute__((warn_unused_result)) status_t registerLazyPassthroughServiceImplementation(
-        const std::string& name = "default") {
-    return details::registerPassthroughServiceImplementation<Interface, ExpectInterface>(
-            [](const sp<Interface>& service, const std::string& name) {
-                using android::hardware::LazyServiceRegistrar;
-                return LazyServiceRegistrar::getInstance().registerService(service, name);
-            },
-            name);
+    const std::string& name = "default") {
+    // Make LazyServiceRegistrar static so that multiple calls to
+    // registerLazyPassthroughServiceImplementation work as expected: each HAL is registered and the
+    // process only exits once all HALs have 0 clients.
+    using android::hardware::LazyServiceRegistrar;
+    static auto serviceCounter(std::make_shared<LazyServiceRegistrar>());
+
+    return details::registerPassthroughServiceImplementation<Interface>(
+        [](const sp<Interface>& service, const std::string& name) {
+            return serviceCounter->registerService(service, name);
+        },
+        name);
 }
 
 /**
@@ -124,12 +121,11 @@
  *
  * Return value is exit status.
  */
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface>
 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
-        const std::string& name, size_t maxThreads = 1) {
+    const std::string& name, size_t maxThreads = 1) {
     configureRpcThreadpool(maxThreads, true);
-    status_t result =
-            registerLazyPassthroughServiceImplementation<Interface, ExpectInterface>(name);
+    status_t result = registerLazyPassthroughServiceImplementation<Interface>(name);
 
     if (result != OK) {
         return result;
@@ -138,11 +134,10 @@
     joinRpcThreadpool();
     return UNKNOWN_ERROR;
 }
-template <class Interface, class ExpectInterface = Interface>
+template <class Interface>
 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
-        size_t maxThreads = 1) {
-    return defaultLazyPassthroughServiceImplementation<Interface, ExpectInterface>("default",
-                                                                                   maxThreads);
+    size_t maxThreads = 1) {
+    return defaultLazyPassthroughServiceImplementation<Interface>("default", maxThreads);
 }
 
 }  // namespace hardware
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
index 4573a25..a962034 100644
--- a/transport/include/hidl/ServiceManagement.h
+++ b/transport/include/hidl/ServiceManagement.h
@@ -18,7 +18,6 @@
 #define ANDROID_HARDWARE_ISERVICE_MANAGER_H
 
 #include <string>
-#include <vector>
 
 #include <android/hidl/base/1.0/IBase.h>
 #include <utils/StrongPointer.h>
@@ -72,14 +71,6 @@
 sp<::android::hidl::manager::V1_1::IServiceManager> getPassthroughServiceManager1_1();
 
 /**
- * Given a descriptor (e.g. from IFoo::descriptor), return a list of all instance names
- * on a device (e.g. the VINTF manifest). These HALs may not be currently running, but
- * the expectation is that if they aren't running, they should start as lazy HALs.
- * So, getService should return for each of these instance names.
- */
-std::vector<std::string> getAllHalInstanceNames(const std::string& descriptor);
-
-/**
  * 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).
  *
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index 3f6203c..be74bae 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -32,6 +32,17 @@
 namespace hardware {
 namespace details {
 
+struct SchedPrio {
+    int sched_policy;
+    int prio;
+};
+
+// TODO(b/69122224): remove this
+extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio>>
+        gServicePrioMap;
+// TODO(b/69122224): remove this
+extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool>> gServiceSidMap;
+
 // TODO(b/69122224): remove this
 // For HidlBinderSupport and autogenerated code
 extern DoNotDestruct<ConcurrentMap<const ::android::hidl::base::V1_0::IBase*,
diff --git a/transport/manager/1.0/Android.bp b/transport/manager/1.0/Android.bp
index c91dcd2..869c58e 100644
--- a/transport/manager/1.0/Android.bp
+++ b/transport/manager/1.0/Android.bp
@@ -15,3 +15,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/manager/1.1/Android.bp b/transport/manager/1.1/Android.bp
index 82545e5..407dfa3 100644
--- a/transport/manager/1.1/Android.bp
+++ b/transport/manager/1.1/Android.bp
@@ -15,3 +15,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/manager/1.2/Android.bp b/transport/manager/1.2/Android.bp
index e7ee143..3f02f78 100644
--- a/transport/manager/1.2/Android.bp
+++ b/transport/manager/1.2/Android.bp
@@ -17,3 +17,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/memory/1.0/Android.bp b/transport/memory/1.0/Android.bp
index dd76889..eaa3037 100644
--- a/transport/memory/1.0/Android.bp
+++ b/transport/memory/1.0/Android.bp
@@ -16,3 +16,4 @@
     ],
     gen_java: false,
 }
+
diff --git a/transport/memory/1.0/default/Android.bp b/transport/memory/1.0/default/Android.bp
index f56ee95..d242ddf 100644
--- a/transport/memory/1.0/default/Android.bp
+++ b/transport/memory/1.0/default/Android.bp
@@ -29,10 +29,12 @@
     ],
     shared_libs: [
         "libcutils",
+        "libhwbinder",
         "libbase",
         "liblog",
         "libutils",
         "libhidlbase",
+        "libhidltransport",
         "android.hidl.memory@1.0",
     ],
 }
diff --git a/transport/memory/1.0/default/HidlFetch.cpp b/transport/memory/1.0/default/HidlFetch.cpp
index a636e03..d47cf97 100644
--- a/transport/memory/1.0/default/HidlFetch.cpp
+++ b/transport/memory/1.0/default/HidlFetch.cpp
@@ -16,11 +16,9 @@
 
 #include "HidlFetch.h"
 
-#include <string_view>
-
 #include "AshmemMapper.h"
 
-static constexpr std::string_view kAshmemMemoryName = "ashmem";
+static std::string kAshmemMemoryName = "ashmem";
 
 namespace android {
 namespace hidl {
diff --git a/transport/safe_union/1.0/Android.bp b/transport/safe_union/1.0/Android.bp
index 2760863..88c7d5d 100644
--- a/transport/safe_union/1.0/Android.bp
+++ b/transport/safe_union/1.0/Android.bp
@@ -12,3 +12,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/token/1.0/Android.bp b/transport/token/1.0/Android.bp
index 28f16f7..c0988cb 100644
--- a/transport/token/1.0/Android.bp
+++ b/transport/token/1.0/Android.bp
@@ -14,3 +14,4 @@
     ],
     gen_java: true,
 }
+
diff --git a/transport/token/1.0/utils/Android.bp b/transport/token/1.0/utils/Android.bp
index 8e23c62..cdbdd97 100644
--- a/transport/token/1.0/utils/Android.bp
+++ b/transport/token/1.0/utils/Android.bp
@@ -25,22 +25,16 @@
         "HybridInterface.cpp",
     ],
 
-    header_libs: [
-        "libbinder_headers",
-    ],
-
     shared_libs: [
         "android.hidl.token@1.0",
+        "libbinder",
         "libhidlbase",
         "liblog",
         "libutils",
     ],
 
-    export_header_lib_headers: [
-        "libbinder_headers",
-    ],
-
     export_shared_lib_headers: [
+        "libbinder",
         "libhidlbase",
     ],
 
diff --git a/transport/token/1.0/utils/HybridInterface.cpp b/transport/token/1.0/utils/HybridInterface.cpp
index 675db8f..106ad4e 100644
--- a/transport/token/1.0/utils/HybridInterface.cpp
+++ b/transport/token/1.0/utils/HybridInterface.cpp
@@ -117,4 +117,5 @@
     return static_cast<bool>(transaction);
 }
 
-}  // namespace android
+}; // namespace android
+
diff --git a/transport/token/1.0/utils/include/hidl/HybridInterface.h b/transport/token/1.0/utils/include/hidl/HybridInterface.h
index d00a0a1..125d5e8 100644
--- a/transport/token/1.0/utils/include/hidl/HybridInterface.h
+++ b/transport/token/1.0/utils/include/hidl/HybridInterface.h
@@ -389,10 +389,7 @@
         return getHalVariant().index();                                   \
     }                                                                     \
     constexpr uint32_t I##INTERFACE::sGetHalTokenTransactionCode;         \
-    static const ::android::StaticString16 I##INTERFACE##_desc_str16(     \
-        u##NAME);                                                         \
-    const ::android::String16 I##INTERFACE::descriptor(                   \
-        I##INTERFACE##_desc_str16);                                       \
+    const ::android::String16 I##INTERFACE::descriptor(NAME);             \
     const ::android::String16&                                            \
             I##INTERFACE::getInterfaceDescriptor() const {                \
         return I##INTERFACE::descriptor;                                  \
@@ -560,6 +557,6 @@
 
 // ----------------------------------------------------------------------
 
-}  // namespace android
+}; // namespace android
 
 #endif // ANDROID_HYBRIDINTERFACE_H