Snap for 5798008 from 5775907bcca7e98bb25af59e0032ffbea950cb46 to sdk-release

Change-Id: I8d893d948842207a1e6f1a7c85b8d2841f6781fd
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index adf86a7..c0ae1c0 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -585,8 +585,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;
diff --git a/libhidlcache/Android.bp b/libhidlcache/Android.bp
deleted file mode 100644
index d28a4f1..0000000
--- a/libhidlcache/Android.bp
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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
deleted file mode 100644
index 39a7b3a..0000000
--- a/libhidlcache/HidlCache.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a23c388..0000000
--- a/libhidlcache/HidlMemoryCache.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c9a533b..0000000
--- a/libhidlcache/HidlMemoryCache.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e5686a7..0000000
--- a/libhidlcache/MemoryDealer.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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
deleted file mode 100644
index fceed83..0000000
--- a/libhidlcache/include/hidlcache/MemoryDealer.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 972b7b5..0000000
--- a/libhidlcache/include/hidlcache/mapping.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e514460..0000000
--- a/libhidlcache/libhidlcache_test.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2a23e6f..0000000
--- a/libhidlcache/mapping.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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/test_main.cpp b/test_main.cpp
index af29f84..7b6781a 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -350,6 +350,41 @@
     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};
diff --git a/transport/base/1.0/vts/functional/Android.bp b/transport/base/1.0/vts/functional/Android.bp
index f0bd45c..fb9af33 100644
--- a/transport/base/1.0/vts/functional/Android.bp
+++ b/transport/base/1.0/vts/functional/Android.bp
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
 cc_test {
     name: "vts_ibase_test",
     srcs: [
@@ -29,6 +28,10 @@
         "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 6d66042..b77b2ad 100644
--- a/transport/base/1.0/vts/functional/vts_ibase_test.cpp
+++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
@@ -13,17 +13,32 @@
  * 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;
@@ -33,8 +48,8 @@
 using android::hardware::toBinder;
 using android::hidl::base::V1_0::IBase;
 using android::hidl::manager::V1_0::IServiceManager;
-using android::sp;
-using android::wp;
+using android::init::ServiceInterfacesMap;
+using PidInterfacesMap = std::map<pid_t, std::set<FqInstance>>;
 
 template <typename T>
 static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
@@ -47,8 +62,40 @@
 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 {
@@ -86,7 +133,7 @@
                     // include all the names this is registered as for error messages
                     iter->second.name += " " + strName;
                 } else {
-                    all_hals_.insert(iter, {binder, Hal{service, strName}});
+                    all_hals_.insert(iter, {binder, Hal{.service = service, .name = strName}});
                 }
             }
         }));
@@ -100,6 +147,25 @@
         }
     }
 
+    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_;
 
@@ -165,6 +231,76 @@
     });
 }
 
+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/memory/1.0/default/HidlFetch.cpp b/transport/memory/1.0/default/HidlFetch.cpp
index d47cf97..a636e03 100644
--- a/transport/memory/1.0/default/HidlFetch.cpp
+++ b/transport/memory/1.0/default/HidlFetch.cpp
@@ -16,9 +16,11 @@
 
 #include "HidlFetch.h"
 
+#include <string_view>
+
 #include "AshmemMapper.h"
 
-static std::string kAshmemMemoryName = "ashmem";
+static constexpr std::string_view kAshmemMemoryName = "ashmem";
 
 namespace android {
 namespace hidl {