AIDL BufferPool implementation (HIDL -> AIDL)

Bug: 254050250
Test: m
Change-Id: I0d7bae2c01bd480d1e99f4b39c4a9013a2828897
diff --git a/media/bufferpool/aidl/default/Accessor.cpp b/media/bufferpool/aidl/default/Accessor.cpp
index e05b12a..3d206ac 100644
--- a/media/bufferpool/aidl/default/Accessor.cpp
+++ b/media/bufferpool/aidl/default/Accessor.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -13,22 +13,60 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "BufferPoolConnection"
+#define LOG_TAG "AidlBufferPoolAcc"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
 
 #include "Accessor.h"
-#include "AccessorImpl.h"
 #include "Connection.h"
+#include "DataHelper.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+    static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
+    static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
+}
+
+#ifdef __ANDROID_VNDK__
+static constexpr uint32_t kSeqIdVndkBit = 1U << 31;
+#else
+static constexpr uint32_t kSeqIdVndkBit = 0;
+#endif
+
+static constexpr uint32_t kSeqIdMax = 0x7fffffff;
+uint32_t Accessor::sSeqId = time(nullptr) & kSeqIdMax;
+
+namespace {
+// anonymous namespace
+static std::shared_ptr<ConnectionDeathRecipient> sConnectionDeathRecipient =
+    std::make_shared<ConnectionDeathRecipient>();
+
+void serviceDied(void *cookie) {
+    if (sConnectionDeathRecipient) {
+        sConnectionDeathRecipient->onDead(cookie);
+    }
+}
+}
+
+std::shared_ptr<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
+    return sConnectionDeathRecipient;
+}
+
+ConnectionDeathRecipient::ConnectionDeathRecipient() {
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
+            AIBinder_DeathRecipient_new(serviceDied));
+}
 
 void ConnectionDeathRecipient::add(
         int64_t connectionId,
-        const sp<Accessor> &accessor) {
+        const std::shared_ptr<Accessor> &accessor) {
     std::lock_guard<std::mutex> lock(mLock);
     if (mAccessors.find(connectionId) == mAccessors.end()) {
         mAccessors.insert(std::make_pair(connectionId, accessor));
@@ -40,7 +78,7 @@
     mAccessors.erase(connectionId);
     auto it = mConnectionToCookie.find(connectionId);
     if (it != mConnectionToCookie.end()) {
-        uint64_t cookie = it->second;
+        void * cookie = it->second;
         mConnectionToCookie.erase(it);
         auto cit = mCookieToConnections.find(cookie);
         if (cit != mCookieToConnections.end()) {
@@ -53,7 +91,7 @@
 }
 
 void ConnectionDeathRecipient::addCookieToConnection(
-        uint64_t cookie,
+        void *cookie,
         int64_t connectionId) {
     std::lock_guard<std::mutex> lock(mLock);
     if (mAccessors.find(connectionId) == mAccessors.end()) {
@@ -69,11 +107,8 @@
     }
 }
 
-void ConnectionDeathRecipient::serviceDied(
-        uint64_t cookie,
-        const wp<::android::hidl::base::V1_0::IBase>& /* who */
-        ) {
-    std::map<int64_t, const wp<Accessor>> connectionsToClose;
+void ConnectionDeathRecipient::onDead(void *cookie) {
+    std::map<int64_t, const std::weak_ptr<Accessor>> connectionsToClose;
     {
         std::lock_guard<std::mutex> lock(mLock);
 
@@ -92,9 +127,9 @@
     }
 
     if (connectionsToClose.size() > 0) {
-        sp<Accessor> accessor;
+        std::shared_ptr<Accessor> accessor;
         for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
-            accessor = it->second.promote();
+            accessor = it->second.lock();
 
             if (accessor) {
                 accessor->close(it->first);
@@ -104,127 +139,371 @@
     }
 }
 
-namespace {
-static sp<ConnectionDeathRecipient> sConnectionDeathRecipient =
-        new ConnectionDeathRecipient();
+AIBinder_DeathRecipient *ConnectionDeathRecipient::getRecipient() {
+    return mDeathRecipient.get();
 }
 
-sp<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
-    return sConnectionDeathRecipient;
-}
-
-void Accessor::createInvalidator() {
-    Accessor::Impl::createInvalidator();
-}
-
-void Accessor::createEvictor() {
-    Accessor::Impl::createEvictor();
-}
-
-// Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
-Return<void> Accessor::connect(
-        const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer,
-        connect_cb _hidl_cb) {
-    sp<Connection> connection;
+::ndk::ScopedAStatus Accessor::connect(const std::shared_ptr<::aidl::android::hardware::media::bufferpool2::IObserver>& in_observer, ::aidl::android::hardware::media::bufferpool2::IAccessor::ConnectionInfo* _aidl_return) {
+    std::shared_ptr<Connection> connection;
     ConnectionId connectionId;
     uint32_t msgId;
-    const StatusDescriptor* fmqDesc;
-    const InvalidationDescriptor* invDesc;
-
-    ResultStatus status = connect(
-            observer, false, &connection, &connectionId, &msgId, &fmqDesc, &invDesc);
+    StatusDescriptor statusDesc;
+    InvalidationDescriptor invDesc;
+    BufferPoolStatus status = connect(
+            in_observer, false, &connection, &connectionId, &msgId, &statusDesc, &invDesc);
     if (status == ResultStatus::OK) {
-        _hidl_cb(status, connection, connectionId, msgId, *fmqDesc, *invDesc);
-    } else {
-        _hidl_cb(status, nullptr, -1LL, 0,
-                 android::hardware::MQDescriptorSync<BufferStatusMessage>(
-                         std::vector<android::hardware::GrantorDescriptor>(),
-                         nullptr /* nhandle */, 0 /* size */),
-                 android::hardware::MQDescriptorUnsync<BufferInvalidationMessage>(
-                         std::vector<android::hardware::GrantorDescriptor>(),
-                         nullptr /* nhandle */, 0 /* size */));
+        _aidl_return->connection = connection;
+        _aidl_return->connectionId = connectionId;
+        _aidl_return->msgId = msgId;
+        _aidl_return->toFmqDesc = std::move(statusDesc);
+        _aidl_return->fromFmqDesc = std::move(invDesc);
+        return ::ndk::ScopedAStatus::ok();
     }
-    return Void();
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
 }
 
 Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
-    : mImpl(new Impl(allocator)) {}
+    : mAllocator(allocator), mScheduleEvictTs(0) {}
 
 Accessor::~Accessor() {
 }
 
 bool Accessor::isValid() {
-    return (bool)mImpl && mImpl->isValid();
+    return mBufferPool.isValid();
 }
 
-ResultStatus Accessor::flush() {
-    if (mImpl) {
-        mImpl->flush();
-        return ResultStatus::OK;
-    }
-    return ResultStatus::CRITICAL_ERROR;
+BufferPoolStatus Accessor::flush() {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.flush(ref<Accessor>());
+    return ResultStatus::OK;
 }
 
-ResultStatus Accessor::allocate(
+BufferPoolStatus Accessor::allocate(
         ConnectionId connectionId,
         const std::vector<uint8_t> &params,
         BufferId *bufferId, const native_handle_t** handle) {
-    if (mImpl) {
-        return mImpl->allocate(connectionId, params, bufferId, handle);
+    std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    BufferPoolStatus status = ResultStatus::OK;
+    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
+        lock.unlock();
+        std::shared_ptr<BufferPoolAllocation> alloc;
+        size_t allocSize;
+        status = mAllocator->allocate(params, &alloc, &allocSize);
+        lock.lock();
+        if (status == ResultStatus::OK) {
+            status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
+        }
+        ALOGV("create a buffer %d : %u %p",
+              status == ResultStatus::OK, *bufferId, *handle);
     }
-    return ResultStatus::CRITICAL_ERROR;
+    if (status == ResultStatus::OK) {
+        // TODO: handle ownBuffer failure
+        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
+    }
+    mBufferPool.cleanUp();
+    scheduleEvictIfNeeded();
+    return status;
 }
 
-ResultStatus Accessor::fetch(
+BufferPoolStatus Accessor::fetch(
         ConnectionId connectionId, TransactionId transactionId,
         BufferId bufferId, const native_handle_t** handle) {
-    if (mImpl) {
-        return mImpl->fetch(connectionId, transactionId, bufferId, handle);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus Accessor::connect(
-        const sp<IObserver> &observer, bool local,
-        sp<Connection> *connection, ConnectionId *pConnectionId,
-        uint32_t *pMsgId,
-        const StatusDescriptor** statusDescPtr,
-        const InvalidationDescriptor** invDescPtr) {
-    if (mImpl) {
-        ResultStatus status = mImpl->connect(
-                this, observer, connection, pConnectionId, pMsgId,
-                statusDescPtr, invDescPtr);
-        if (!local && status == ResultStatus::OK) {
-            sp<Accessor> accessor(this);
-            sConnectionDeathRecipient->add(*pConnectionId, accessor);
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    auto found = mBufferPool.mTransactions.find(transactionId);
+    if (found != mBufferPool.mTransactions.end() &&
+            contains(&mBufferPool.mPendingTransactions,
+                     connectionId, transactionId)) {
+        if (found->second->mSenderValidated &&
+                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
+                found->second->mBufferId == bufferId) {
+            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
+            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
+            if (bufferIt != mBufferPool.mBuffers.end()) {
+                mBufferPool.mStats.onBufferFetched();
+                *handle = bufferIt->second->handle();
+                return ResultStatus::OK;
+            }
         }
-        return status;
     }
+    mBufferPool.cleanUp();
+    scheduleEvictIfNeeded();
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus Accessor::close(ConnectionId connectionId) {
-    if (mImpl) {
-        ResultStatus status = mImpl->close(connectionId);
-        sConnectionDeathRecipient->remove(connectionId);
-        return status;
+BufferPoolStatus Accessor::connect(
+        const std::shared_ptr<IObserver> &observer, bool local,
+        std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
+        uint32_t *pMsgId,
+        StatusDescriptor* statusDescPtr,
+        InvalidationDescriptor* invDescPtr) {
+    std::shared_ptr<Connection> newConnection = ::ndk::SharedRefBase::make<Connection>();
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        if (newConnection) {
+            int32_t pid = getpid();
+            ConnectionId id = (int64_t)pid << 32 | sSeqId | kSeqIdVndkBit;
+            status = mBufferPool.mObserver.open(id, statusDescPtr);
+            if (status == ResultStatus::OK) {
+                newConnection->initialize(ref<Accessor>(), id);
+                *connection = newConnection;
+                *pConnectionId = id;
+                *pMsgId = mBufferPool.mInvalidation.mInvalidationId;
+                mBufferPool.mConnectionIds.insert(id);
+                mBufferPool.mInvalidationChannel.getDesc(invDescPtr);
+                mBufferPool.mInvalidation.onConnect(id, observer);
+                if (sSeqId == kSeqIdMax) {
+                   sSeqId = 0;
+                } else {
+                    ++sSeqId;
+                }
+            }
+
+        }
+        mBufferPool.processStatusMessages();
+        mBufferPool.cleanUp();
+        scheduleEvictIfNeeded();
     }
-    return ResultStatus::CRITICAL_ERROR;
+    if (!local && status == ResultStatus::OK) {
+        std::shared_ptr<Accessor> accessor(ref<Accessor>());
+        sConnectionDeathRecipient->add(*pConnectionId, accessor);
+    }
+    return status;
+}
+
+BufferPoolStatus Accessor::close(ConnectionId connectionId) {
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        ALOGV("connection close %lld: %u", (long long)connectionId, mBufferPool.mInvalidation.mId);
+        mBufferPool.processStatusMessages();
+        mBufferPool.handleClose(connectionId);
+        mBufferPool.mObserver.close(connectionId);
+        mBufferPool.mInvalidation.onClose(connectionId);
+        // Since close# will be called after all works are finished, it is OK to
+        // evict unused buffers.
+        mBufferPool.cleanUp(true);
+        scheduleEvictIfNeeded();
+    }
+    sConnectionDeathRecipient->remove(connectionId);
+    return ResultStatus::OK;
 }
 
 void Accessor::cleanUp(bool clearCache) {
-    if (mImpl) {
-        mImpl->cleanUp(clearCache);
+    // transaction timeout, buffer caching TTL handling
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.cleanUp(clearCache);
+}
+
+void Accessor::handleInvalidateAck() {
+    std::map<ConnectionId, const std::shared_ptr<IObserver>> observers;
+    uint32_t invalidationId;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        mBufferPool.processStatusMessages();
+        mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+    }
+    // Do not hold lock for send invalidations
+    size_t deadClients = 0;
+    for (auto it = observers.begin(); it != observers.end(); ++it) {
+        const std::shared_ptr<IObserver> observer = it->second;
+        if (observer) {
+            ::ndk::ScopedAStatus status = observer->onMessage(it->first, invalidationId);
+            if (!status.isOk()) {
+                ++deadClients;
+            }
+        }
+    }
+    if (deadClients > 0) {
+        ALOGD("During invalidation found %zu dead clients", deadClients);
     }
 }
 
-//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
-//    return new Accessor();
-//}
+void Accessor::invalidatorThread(
+            std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+            std::mutex &mutex,
+            std::condition_variable &cv,
+            bool &ready) {
+    constexpr uint32_t NUM_SPIN_TO_INCREASE_SLEEP = 1024;
+    constexpr uint32_t NUM_SPIN_TO_LOG = 1024*8;
+    constexpr useconds_t MAX_SLEEP_US = 10000;
+    uint32_t numSpin = 0;
+    useconds_t sleepUs = 1;
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+    while(true) {
+        std::map<uint32_t, const std::weak_ptr<Accessor>> copied;
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            while (!ready) {
+                numSpin = 0;
+                sleepUs = 1;
+                cv.wait(lock);
+            }
+            copied.insert(accessors.begin(), accessors.end());
+        }
+        std::list<ConnectionId> erased;
+        for (auto it = copied.begin(); it != copied.end(); ++it) {
+            const std::shared_ptr<Accessor> acc = it->second.lock();
+            if (!acc) {
+                erased.push_back(it->first);
+            } else {
+                acc->handleInvalidateAck();
+            }
+        }
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            for (auto it = erased.begin(); it != erased.end(); ++it) {
+                accessors.erase(*it);
+            }
+            if (accessors.size() == 0) {
+                ready = false;
+            } else {
+                // N.B. Since there is not a efficient way to wait over FMQ,
+                // polling over the FMQ is the current way to prevent draining
+                // CPU.
+                lock.unlock();
+                ++numSpin;
+                if (numSpin % NUM_SPIN_TO_INCREASE_SLEEP == 0 &&
+                    sleepUs < MAX_SLEEP_US) {
+                    sleepUs *= 10;
+                }
+                if (numSpin % NUM_SPIN_TO_LOG == 0) {
+                    ALOGW("invalidator thread spinning");
+                }
+                ::usleep(sleepUs);
+            }
+        }
+    }
+}
+
+Accessor::AccessorInvalidator::AccessorInvalidator() : mReady(false) {
+    std::thread invalidator(
+            invalidatorThread,
+            std::ref(mAccessors),
+            std::ref(mMutex),
+            std::ref(mCv),
+            std::ref(mReady));
+    invalidator.detach();
+}
+
+void Accessor::AccessorInvalidator::addAccessor(
+        uint32_t accessorId, const std::weak_ptr<Accessor> &accessor) {
+    bool notify = false;
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (mAccessors.find(accessorId) == mAccessors.end()) {
+        if (!mReady) {
+            mReady = true;
+            notify = true;
+        }
+        mAccessors.emplace(accessorId, accessor);
+        ALOGV("buffer invalidation added bp:%u %d", accessorId, notify);
+    }
+    lock.unlock();
+    if (notify) {
+        mCv.notify_one();
+    }
+}
+
+void Accessor::AccessorInvalidator::delAccessor(uint32_t accessorId) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mAccessors.erase(accessorId);
+    ALOGV("buffer invalidation deleted bp:%u", accessorId);
+    if (mAccessors.size() == 0) {
+        mReady = false;
+    }
+}
+
+std::unique_ptr<Accessor::AccessorInvalidator> Accessor::sInvalidator;
+
+void Accessor::createInvalidator() {
+    if (!sInvalidator) {
+        sInvalidator = std::make_unique<Accessor::AccessorInvalidator>();
+    }
+}
+
+void Accessor::evictorThread(
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv) {
+    std::list<const std::weak_ptr<Accessor>> evictList;
+    while (true) {
+        int expired = 0;
+        int evicted = 0;
+        {
+            nsecs_t now = systemTime();
+            std::unique_lock<std::mutex> lock(mutex);
+            while (accessors.size() == 0) {
+                cv.wait(lock);
+            }
+            auto it = accessors.begin();
+            while (it != accessors.end()) {
+                if (now > (it->second + kEvictDurationNs)) {
+                    ++expired;
+                    evictList.push_back(it->first);
+                    it = accessors.erase(it);
+                } else {
+                    ++it;
+                }
+            }
+        }
+        // evict idle accessors;
+        for (auto it = evictList.begin(); it != evictList.end(); ++it) {
+            const std::shared_ptr<Accessor> accessor = it->lock();
+            if (accessor) {
+                accessor->cleanUp(true);
+                ++evicted;
+            }
+        }
+        if (expired > 0) {
+            ALOGD("evictor expired: %d, evicted: %d", expired, evicted);
+        }
+        evictList.clear();
+        ::usleep(kEvictGranularityNs / 1000);
+    }
+}
+
+Accessor::AccessorEvictor::AccessorEvictor() {
+    std::thread evictor(
+            evictorThread,
+            std::ref(mAccessors),
+            std::ref(mMutex),
+            std::ref(mCv));
+    evictor.detach();
+}
+
+void Accessor::AccessorEvictor::addAccessor(
+        const std::weak_ptr<Accessor> &accessor, nsecs_t ts) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    bool notify = mAccessors.empty();
+    auto it = mAccessors.find(accessor);
+    if (it == mAccessors.end()) {
+        mAccessors.emplace(accessor, ts);
+    } else {
+        it->second = ts;
+    }
+    if (notify) {
+        mCv.notify_one();
+    }
+}
+
+std::unique_ptr<Accessor::AccessorEvictor> Accessor::sEvictor;
+
+void Accessor::createEvictor() {
+    if (!sEvictor) {
+        sEvictor = std::make_unique<Accessor::AccessorEvictor>();
+    }
+}
+
+void Accessor::scheduleEvictIfNeeded() {
+    nsecs_t now = systemTime();
+
+    if (now > (mScheduleEvictTs + kEvictGranularityNs)) {
+        mScheduleEvictTs = now;
+        sEvictor->addAccessor(ref<Accessor>(), now);
+    }
+}
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implemntation {
diff --git a/media/bufferpool/aidl/default/Accessor.h b/media/bufferpool/aidl/default/Accessor.h
index 8b43301..85e2fa7 100644
--- a/media/bufferpool/aidl/default/Accessor.h
+++ b/media/bufferpool/aidl/default/Accessor.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,73 +14,65 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
+#pragma once
 
-#include <android/hardware/media/bufferpool/2.0/IAccessor.h>
-#include <android/hardware/media/bufferpool/2.0/IObserver.h>
-#include <bufferpool/BufferPoolTypes.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include "BufferStatus.h"
+#include <aidl/android/hardware/media/bufferpool2/BnAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
 
+#include <memory>
+#include <map>
 #include <set>
+#include <condition_variable>
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+#include "BufferPool.h"
 
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-struct Accessor;
 struct Connection;
+using ::aidl::android::hardware::media::bufferpool2::IObserver;
+using ::aidl::android::hardware::media::bufferpool2::IAccessor;
 
 /**
  * Receives death notifications from remote connections.
  * On death notifications, the connections are closed and used resources
  * are released.
  */
-struct ConnectionDeathRecipient : public hardware::hidl_death_recipient {
+struct ConnectionDeathRecipient {
+    ConnectionDeathRecipient();
     /**
      * Registers a newly connected connection from remote processes.
      */
-    void add(int64_t connectionId, const sp<Accessor> &accessor);
+    void add(int64_t connectionId, const std::shared_ptr<Accessor> &accessor);
 
     /**
      * Removes a connection.
      */
     void remove(int64_t connectionId);
 
-    void addCookieToConnection(uint64_t cookie, int64_t connectionId);
+    void addCookieToConnection(void *cookie, int64_t connectionId);
 
-    virtual void serviceDied(
-            uint64_t /* cookie */,
-            const wp<::android::hidl::base::V1_0::IBase>& /* who */
-            ) override;
+    void onDead(void *cookie);
+
+    AIBinder_DeathRecipient *getRecipient();
 
 private:
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
     std::mutex mLock;
-    std::map<uint64_t, std::set<int64_t>>  mCookieToConnections;
-    std::map<int64_t, uint64_t> mConnectionToCookie;
-    std::map<int64_t, const wp<Accessor>> mAccessors;
+    std::map<void *, std::set<int64_t>>  mCookieToConnections;
+    std::map<int64_t, void *> mConnectionToCookie;
+    std::map<int64_t, const std::weak_ptr<Accessor>> mAccessors;
 };
 
 /**
  * A buffer pool accessor which enables a buffer pool to communicate with buffer
  * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
  */
-struct Accessor : public IAccessor {
-    // Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
-    Return<void> connect(const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer, connect_cb _hidl_cb) override;
+struct Accessor : public BnAccessor {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IAccessor.
+    ::ndk::ScopedAStatus connect(const std::shared_ptr<IObserver>& in_observer,
+                                 IAccessor::ConnectionInfo* _aidl_return) override;
 
     /**
      * Creates a buffer pool accessor which uses the specified allocator.
@@ -96,7 +88,7 @@
     bool isValid();
 
     /** Invalidates all buffers which are owned by bufferpool */
-    ResultStatus flush();
+    BufferPoolStatus flush();
 
     /** Allocates a buffer from a buffer pool.
      *
@@ -109,7 +101,7 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus allocate(
+    BufferPoolStatus allocate(
             ConnectionId connectionId,
             const std::vector<uint8_t>& params,
             BufferId *bufferId,
@@ -127,7 +119,7 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus fetch(
+    BufferPoolStatus fetch(
             ConnectionId connectionId,
             TransactionId transactionId,
             BufferId bufferId,
@@ -153,13 +145,13 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus connect(
-            const sp<IObserver>& observer,
+    BufferPoolStatus connect(
+            const std::shared_ptr<IObserver>& observer,
             bool local,
-            sp<Connection> *connection, ConnectionId *pConnectionId,
+            std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
             uint32_t *pMsgId,
-            const StatusDescriptor** statusDescPtr,
-            const InvalidationDescriptor** invDescPtr);
+            StatusDescriptor* statusDescPtr,
+            InvalidationDescriptor* invDescPtr);
 
     /**
      * Closes the specified connection to the client.
@@ -169,10 +161,10 @@
      * @return OK when the connection is closed.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus close(ConnectionId connectionId);
+    BufferPoolStatus close(ConnectionId connectionId);
 
     /**
-     * Processes pending buffer status messages and perfoms periodic cache
+     * Processes pending buffer status messages and performs periodic cache
      * cleaning.
      *
      * @param clearCache    if clearCache is true, it frees all buffers waiting
@@ -181,24 +173,66 @@
     void cleanUp(bool clearCache);
 
     /**
-     * Gets a hidl_death_recipient for remote connection death.
+     * ACK on buffer invalidation messages
      */
-    static sp<ConnectionDeathRecipient> getConnectionDeathRecipient();
+    void handleInvalidateAck();
+
+    /**
+     * Gets a death_recipient for remote connection death.
+     */
+    static std::shared_ptr<ConnectionDeathRecipient> getConnectionDeathRecipient();
 
     static void createInvalidator();
 
     static void createEvictor();
 
 private:
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
+    // ConnectionId = pid : (timestamp_created + seqId)
+    // in order to guarantee uniqueness for each connection
+    static uint32_t sSeqId;
+
+    const std::shared_ptr<BufferPoolAllocator> mAllocator;
+    nsecs_t mScheduleEvictTs;
+    BufferPool mBufferPool;
+
+    struct  AccessorInvalidator {
+        std::map<uint32_t, const std::weak_ptr<Accessor>> mAccessors;
+        std::mutex mMutex;
+        std::condition_variable mCv;
+        bool mReady;
+
+        AccessorInvalidator();
+        void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor> &accessor);
+        void delAccessor(uint32_t accessorId);
+    };
+
+    static std::unique_ptr<AccessorInvalidator> sInvalidator;
+
+    static void invalidatorThread(
+        std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv,
+        bool &ready);
+
+    struct AccessorEvictor {
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> mAccessors;
+        std::mutex mMutex;
+        std::condition_variable mCv;
+
+        AccessorEvictor();
+        void addAccessor(const std::weak_ptr<Accessor> &accessor, nsecs_t ts);
+    };
+
+    static std::unique_ptr<AccessorEvictor> sEvictor;
+
+    static void evictorThread(
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv);
+
+    void scheduleEvictIfNeeded();
+
+    friend struct BufferPool;
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSOR_H
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/AccessorImpl.cpp b/media/bufferpool/aidl/default/AccessorImpl.cpp
deleted file mode 100644
index 1d2562e..0000000
--- a/media/bufferpool/aidl/default/AccessorImpl.cpp
+++ /dev/null
@@ -1,993 +0,0 @@
-/*
- * Copyright (C) 2018 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 "BufferPoolAccessor2.0"
-//#define LOG_NDEBUG 0
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <time.h>
-#include <unistd.h>
-#include <utils/Log.h>
-#include <thread>
-#include "AccessorImpl.h"
-#include "Connection.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
-
-namespace {
-    static constexpr int64_t kCleanUpDurationUs = 500000; // TODO tune 0.5 sec
-    static constexpr int64_t kLogDurationUs = 5000000; // 5 secs
-
-    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
-    static constexpr size_t kMinBufferCountForEviction = 25;
-    static constexpr size_t kMaxUnusedBufferCount = 64;
-    static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
-
-    static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
-    static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
-}
-
-// Buffer structure in bufferpool process
-struct InternalBuffer {
-    BufferId mId;
-    size_t mOwnerCount;
-    size_t mTransactionCount;
-    const std::shared_ptr<BufferPoolAllocation> mAllocation;
-    const size_t mAllocSize;
-    const std::vector<uint8_t> mConfig;
-    bool mInvalidated;
-
-    InternalBuffer(
-            BufferId id,
-            const std::shared_ptr<BufferPoolAllocation> &alloc,
-            const size_t allocSize,
-            const std::vector<uint8_t> &allocConfig)
-            : mId(id), mOwnerCount(0), mTransactionCount(0),
-            mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig),
-            mInvalidated(false) {}
-
-    const native_handle_t *handle() {
-        return mAllocation->handle();
-    }
-
-    void invalidate() {
-        mInvalidated = true;
-    }
-};
-
-struct TransactionStatus {
-    TransactionId mId;
-    BufferId mBufferId;
-    ConnectionId mSender;
-    ConnectionId mReceiver;
-    BufferStatus mStatus;
-    int64_t mTimestampUs;
-    bool mSenderValidated;
-
-    TransactionStatus(const BufferStatusMessage &message, int64_t timestampUs) {
-        mId = message.transactionId;
-        mBufferId = message.bufferId;
-        mStatus = message.newStatus;
-        mTimestampUs = timestampUs;
-        if (mStatus == BufferStatus::TRANSFER_TO) {
-            mSender = message.connectionId;
-            mReceiver = message.targetConnectionId;
-            mSenderValidated = true;
-        } else {
-            mSender = -1LL;
-            mReceiver = message.connectionId;
-            mSenderValidated = false;
-        }
-    }
-};
-
-// Helper template methods for handling map of set.
-template<class T, class U>
-bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    auto iter = mapOfSet->find(key);
-    if (iter == mapOfSet->end()) {
-        std::set<U> valueSet{value};
-        mapOfSet->insert(std::make_pair(key, valueSet));
-        return true;
-    } else if (iter->second.find(value)  == iter->second.end()) {
-        iter->second.insert(value);
-        return true;
-    }
-    return false;
-}
-
-template<class T, class U>
-bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    bool ret = false;
-    auto iter = mapOfSet->find(key);
-    if (iter != mapOfSet->end()) {
-        if (iter->second.erase(value) > 0) {
-            ret = true;
-        }
-        if (iter->second.size() == 0) {
-            mapOfSet->erase(iter);
-        }
-    }
-    return ret;
-}
-
-template<class T, class U>
-bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    auto iter = mapOfSet->find(key);
-    if (iter != mapOfSet->end()) {
-        auto setIter = iter->second.find(value);
-        return setIter != iter->second.end();
-    }
-    return false;
-}
-
-#ifdef __ANDROID_VNDK__
-static constexpr uint32_t kSeqIdVndkBit = 1U << 31;
-#else
-static constexpr uint32_t kSeqIdVndkBit = 0;
-#endif
-
-static constexpr uint32_t kSeqIdMax = 0x7fffffff;
-uint32_t Accessor::Impl::sSeqId = time(nullptr) & kSeqIdMax;
-
-Accessor::Impl::Impl(
-        const std::shared_ptr<BufferPoolAllocator> &allocator)
-        : mAllocator(allocator), mScheduleEvictTs(0) {}
-
-Accessor::Impl::~Impl() {
-}
-
-ResultStatus Accessor::Impl::connect(
-        const sp<Accessor> &accessor, const sp<IObserver> &observer,
-        sp<Connection> *connection,
-        ConnectionId *pConnectionId,
-        uint32_t *pMsgId,
-        const StatusDescriptor** statusDescPtr,
-        const InvalidationDescriptor** invDescPtr) {
-    sp<Connection> newConnection = new Connection();
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
-    {
-        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-        if (newConnection) {
-            int32_t pid = getpid();
-            ConnectionId id = (int64_t)pid << 32 | sSeqId | kSeqIdVndkBit;
-            status = mBufferPool.mObserver.open(id, statusDescPtr);
-            if (status == ResultStatus::OK) {
-                newConnection->initialize(accessor, id);
-                *connection = newConnection;
-                *pConnectionId = id;
-                *pMsgId = mBufferPool.mInvalidation.mInvalidationId;
-                mBufferPool.mConnectionIds.insert(id);
-                mBufferPool.mInvalidationChannel.getDesc(invDescPtr);
-                mBufferPool.mInvalidation.onConnect(id, observer);
-                if (sSeqId == kSeqIdMax) {
-                   sSeqId = 0;
-                } else {
-                    ++sSeqId;
-                }
-            }
-
-        }
-        mBufferPool.processStatusMessages();
-        mBufferPool.cleanUp();
-        scheduleEvictIfNeeded();
-    }
-    return status;
-}
-
-ResultStatus Accessor::Impl::close(ConnectionId connectionId) {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    ALOGV("connection close %lld: %u", (long long)connectionId, mBufferPool.mInvalidation.mId);
-    mBufferPool.processStatusMessages();
-    mBufferPool.handleClose(connectionId);
-    mBufferPool.mObserver.close(connectionId);
-    mBufferPool.mInvalidation.onClose(connectionId);
-    // Since close# will be called after all works are finished, it is OK to
-    // evict unused buffers.
-    mBufferPool.cleanUp(true);
-    scheduleEvictIfNeeded();
-    return ResultStatus::OK;
-}
-
-ResultStatus Accessor::Impl::allocate(
-        ConnectionId connectionId, const std::vector<uint8_t>& params,
-        BufferId *bufferId, const native_handle_t** handle) {
-    std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    ResultStatus status = ResultStatus::OK;
-    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
-        lock.unlock();
-        std::shared_ptr<BufferPoolAllocation> alloc;
-        size_t allocSize;
-        status = mAllocator->allocate(params, &alloc, &allocSize);
-        lock.lock();
-        if (status == ResultStatus::OK) {
-            status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
-        }
-        ALOGV("create a buffer %d : %u %p",
-              status == ResultStatus::OK, *bufferId, *handle);
-    }
-    if (status == ResultStatus::OK) {
-        // TODO: handle ownBuffer failure
-        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
-    }
-    mBufferPool.cleanUp();
-    scheduleEvictIfNeeded();
-    return status;
-}
-
-ResultStatus Accessor::Impl::fetch(
-        ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, const native_handle_t** handle) {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    auto found = mBufferPool.mTransactions.find(transactionId);
-    if (found != mBufferPool.mTransactions.end() &&
-            contains(&mBufferPool.mPendingTransactions,
-                     connectionId, transactionId)) {
-        if (found->second->mSenderValidated &&
-                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
-                found->second->mBufferId == bufferId) {
-            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
-            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
-            if (bufferIt != mBufferPool.mBuffers.end()) {
-                mBufferPool.mStats.onBufferFetched();
-                *handle = bufferIt->second->handle();
-                return ResultStatus::OK;
-            }
-        }
-    }
-    mBufferPool.cleanUp();
-    scheduleEvictIfNeeded();
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-void Accessor::Impl::cleanUp(bool clearCache) {
-    // transaction timeout, buffer cacheing TTL handling
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    mBufferPool.cleanUp(clearCache);
-}
-
-void Accessor::Impl::flush() {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    mBufferPool.flush(shared_from_this());
-}
-
-void Accessor::Impl::handleInvalidateAck() {
-    std::map<ConnectionId, const sp<IObserver>> observers;
-    uint32_t invalidationId;
-    {
-        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-        mBufferPool.processStatusMessages();
-        mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
-    }
-    // Do not hold lock for send invalidations
-    size_t deadClients = 0;
-    for (auto it = observers.begin(); it != observers.end(); ++it) {
-        const sp<IObserver> observer = it->second;
-        if (observer) {
-            Return<void> transResult = observer->onMessage(it->first, invalidationId);
-            if (!transResult.isOk()) {
-                ++deadClients;
-            }
-        }
-    }
-    if (deadClients > 0) {
-        ALOGD("During invalidation found %zu dead clients", deadClients);
-    }
-}
-
-bool Accessor::Impl::isValid() {
-    return mBufferPool.isValid();
-}
-
-Accessor::Impl::Impl::BufferPool::BufferPool()
-    : mTimestampUs(getTimestampNow()),
-      mLastCleanUpUs(mTimestampUs),
-      mLastLogUs(mTimestampUs),
-      mSeq(0),
-      mStartSeq(0) {
-    mValid = mInvalidationChannel.isValid();
-}
-
-
-// Statistics helper
-template<typename T, typename S>
-int percentage(T base, S total) {
-    return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
-}
-
-std::atomic<std::uint32_t> Accessor::Impl::BufferPool::Invalidation::sInvSeqId(0);
-
-Accessor::Impl::Impl::BufferPool::~BufferPool() {
-    std::lock_guard<std::mutex> lock(mMutex);
-    ALOGD("Destruction - bufferpool2 %p "
-          "cached: %zu/%zuM, %zu/%d%% in use; "
-          "allocs: %zu, %d%% recycled; "
-          "transfers: %zu, %d%% unfetched",
-          this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
-          mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
-          mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
-          mStats.mTotalTransfers,
-          percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onConnect(
-        ConnectionId conId, const sp<IObserver>& observer) {
-    mAcks[conId] = mInvalidationId; // starts from current invalidationId
-    mObservers.insert(std::make_pair(conId, observer));
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onClose(ConnectionId conId) {
-    mAcks.erase(conId);
-    mObservers.erase(conId);
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onAck(
-        ConnectionId conId,
-        uint32_t msgId) {
-    auto it = mAcks.find(conId);
-    if (it == mAcks.end()) {
-        ALOGW("ACK from inconsistent connection! %lld", (long long)conId);
-        return;
-    }
-    if (isMessageLater(msgId, it->second)) {
-        mAcks[conId] = msgId;
-    }
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onBufferInvalidated(
-        BufferId bufferId,
-        BufferInvalidationChannel &channel) {
-    for (auto it = mPendings.begin(); it != mPendings.end();) {
-        if (it->isInvalidated(bufferId)) {
-            uint32_t msgId = 0;
-            if (it->mNeedsAck) {
-                msgId = ++mInvalidationId;
-                if (msgId == 0) {
-                    // wrap happens
-                    msgId = ++mInvalidationId;
-                }
-            }
-            channel.postInvalidation(msgId, it->mFrom, it->mTo);
-            it = mPendings.erase(it);
-            continue;
-        }
-        ++it;
-    }
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onInvalidationRequest(
-        bool needsAck,
-        uint32_t from,
-        uint32_t to,
-        size_t left,
-        BufferInvalidationChannel &channel,
-        const std::shared_ptr<Accessor::Impl> &impl) {
-        uint32_t msgId = 0;
-    if (needsAck) {
-        msgId = ++mInvalidationId;
-        if (msgId == 0) {
-            // wrap happens
-            msgId = ++mInvalidationId;
-        }
-    }
-    ALOGV("bufferpool2 invalidation requested and queued");
-    if (left == 0) {
-        channel.postInvalidation(msgId, from, to);
-    } else {
-        // TODO: sending hint message?
-        ALOGV("bufferpoo2 invalidation requested and pending");
-        Pending pending(needsAck, from, to, left, impl);
-        mPendings.push_back(pending);
-    }
-    sInvalidator->addAccessor(mId, impl);
-}
-
-void Accessor::Impl::BufferPool::Invalidation::onHandleAck(
-        std::map<ConnectionId, const sp<IObserver>> *observers,
-        uint32_t *invalidationId) {
-    if (mInvalidationId != 0) {
-        *invalidationId = mInvalidationId;
-        std::set<int> deads;
-        for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
-            if (it->second != mInvalidationId) {
-                const sp<IObserver> observer = mObservers[it->first];
-                if (observer) {
-                    observers->emplace(it->first, observer);
-                    ALOGV("connection %lld will call observer (%u: %u)",
-                          (long long)it->first, it->second, mInvalidationId);
-                    // N.B: onMessage will be called later. ignore possibility of
-                    // onMessage# oneway call being lost.
-                    it->second = mInvalidationId;
-                } else {
-                    ALOGV("bufferpool2 observer died %lld", (long long)it->first);
-                    deads.insert(it->first);
-                }
-            }
-        }
-        if (deads.size() > 0) {
-            for (auto it = deads.begin(); it != deads.end(); ++it) {
-                onClose(*it);
-            }
-        }
-    }
-    if (mPendings.size() == 0) {
-        // All invalidation Ids are synced and no more pending invalidations.
-        sInvalidator->delAccessor(mId);
-    }
-}
-
-bool Accessor::Impl::BufferPool::handleOwnBuffer(
-        ConnectionId connectionId, BufferId bufferId) {
-
-    bool added = insert(&mUsingBuffers, connectionId, bufferId);
-    if (added) {
-        auto iter = mBuffers.find(bufferId);
-        iter->second->mOwnerCount++;
-    }
-    insert(&mUsingConnections, bufferId, connectionId);
-    return added;
-}
-
-bool Accessor::Impl::BufferPool::handleReleaseBuffer(
-        ConnectionId connectionId, BufferId bufferId) {
-    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
-    if (deleted) {
-        auto iter = mBuffers.find(bufferId);
-        iter->second->mOwnerCount--;
-        if (iter->second->mOwnerCount == 0 &&
-                iter->second->mTransactionCount == 0) {
-            if (!iter->second->mInvalidated) {
-                mStats.onBufferUnused(iter->second->mAllocSize);
-                mFreeBuffers.insert(bufferId);
-            } else {
-                mStats.onBufferUnused(iter->second->mAllocSize);
-                mStats.onBufferEvicted(iter->second->mAllocSize);
-                mBuffers.erase(iter);
-                mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
-            }
-        }
-    }
-    erase(&mUsingConnections, bufferId, connectionId);
-    ALOGV("release buffer %u : %d", bufferId, deleted);
-    return deleted;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferTo(const BufferStatusMessage &message) {
-    auto completed = mCompletedTransactions.find(
-            message.transactionId);
-    if (completed != mCompletedTransactions.end()) {
-        // already completed
-        mCompletedTransactions.erase(completed);
-        return true;
-    }
-    // the buffer should exist and be owned.
-    auto bufferIter = mBuffers.find(message.bufferId);
-    if (bufferIter == mBuffers.end() ||
-            !contains(&mUsingBuffers, message.connectionId, message.bufferId)) {
-        return false;
-    }
-    auto found = mTransactions.find(message.transactionId);
-    if (found != mTransactions.end()) {
-        // transfer_from was received earlier.
-        found->second->mSender = message.connectionId;
-        found->second->mSenderValidated = true;
-        return true;
-    }
-    if (mConnectionIds.find(message.targetConnectionId) == mConnectionIds.end()) {
-        // N.B: it could be fake or receive connection already closed.
-        ALOGD("bufferpool2 %p receiver connection %lld is no longer valid",
-              this, (long long)message.targetConnectionId);
-        return false;
-    }
-    mStats.onBufferSent();
-    mTransactions.insert(std::make_pair(
-            message.transactionId,
-            std::make_unique<TransactionStatus>(message, mTimestampUs)));
-    insert(&mPendingTransactions, message.targetConnectionId,
-           message.transactionId);
-    bufferIter->second->mTransactionCount++;
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
-    auto found = mTransactions.find(message.transactionId);
-    if (found == mTransactions.end()) {
-        // TODO: is it feasible to check ownership here?
-        mStats.onBufferSent();
-        mTransactions.insert(std::make_pair(
-                message.transactionId,
-                std::make_unique<TransactionStatus>(message, mTimestampUs)));
-        insert(&mPendingTransactions, message.connectionId,
-               message.transactionId);
-        auto bufferIter = mBuffers.find(message.bufferId);
-        bufferIter->second->mTransactionCount++;
-    } else {
-        if (message.connectionId == found->second->mReceiver) {
-            found->second->mStatus = BufferStatus::TRANSFER_FROM;
-        }
-    }
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferResult(const BufferStatusMessage &message) {
-    auto found = mTransactions.find(message.transactionId);
-    if (found != mTransactions.end()) {
-        bool deleted = erase(&mPendingTransactions, message.connectionId,
-                             message.transactionId);
-        if (deleted) {
-            if (!found->second->mSenderValidated) {
-                mCompletedTransactions.insert(message.transactionId);
-            }
-            auto bufferIter = mBuffers.find(message.bufferId);
-            if (message.newStatus == BufferStatus::TRANSFER_OK) {
-                handleOwnBuffer(message.connectionId, message.bufferId);
-            }
-            bufferIter->second->mTransactionCount--;
-            if (bufferIter->second->mOwnerCount == 0
-                && bufferIter->second->mTransactionCount == 0) {
-                if (!bufferIter->second->mInvalidated) {
-                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                    mFreeBuffers.insert(message.bufferId);
-                } else {
-                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                    mStats.onBufferEvicted(bufferIter->second->mAllocSize);
-                    mBuffers.erase(bufferIter);
-                    mInvalidation.onBufferInvalidated(message.bufferId, mInvalidationChannel);
-                }
-            }
-            mTransactions.erase(found);
-        }
-        ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
-              message.bufferId, deleted);
-        return deleted;
-    }
-    ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
-          message.bufferId);
-    return false;
-}
-
-void Accessor::Impl::BufferPool::processStatusMessages() {
-    std::vector<BufferStatusMessage> messages;
-    mObserver.getBufferStatusChanges(messages);
-    mTimestampUs = getTimestampNow();
-    for (BufferStatusMessage& message: messages) {
-        bool ret = false;
-        switch (message.newStatus) {
-            case BufferStatus::NOT_USED:
-                ret = handleReleaseBuffer(
-                        message.connectionId, message.bufferId);
-                break;
-            case BufferStatus::USED:
-                // not happening
-                break;
-            case BufferStatus::TRANSFER_TO:
-                ret = handleTransferTo(message);
-                break;
-            case BufferStatus::TRANSFER_FROM:
-                ret = handleTransferFrom(message);
-                break;
-            case BufferStatus::TRANSFER_TIMEOUT:
-                // TODO
-                break;
-            case BufferStatus::TRANSFER_LOST:
-                // TODO
-                break;
-            case BufferStatus::TRANSFER_FETCH:
-                // not happening
-                break;
-            case BufferStatus::TRANSFER_OK:
-            case BufferStatus::TRANSFER_ERROR:
-                ret = handleTransferResult(message);
-                break;
-            case BufferStatus::INVALIDATION_ACK:
-                mInvalidation.onAck(message.connectionId, message.bufferId);
-                ret = true;
-                break;
-        }
-        if (ret == false) {
-            ALOGW("buffer status message processing failure - message : %d connection : %lld",
-                  message.newStatus, (long long)message.connectionId);
-        }
-    }
-    messages.clear();
-}
-
-bool Accessor::Impl::BufferPool::handleClose(ConnectionId connectionId) {
-    // Cleaning buffers
-    auto buffers = mUsingBuffers.find(connectionId);
-    if (buffers != mUsingBuffers.end()) {
-        for (const BufferId& bufferId : buffers->second) {
-            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
-            if (deleted) {
-                auto bufferIter = mBuffers.find(bufferId);
-                bufferIter->second->mOwnerCount--;
-                if (bufferIter->second->mOwnerCount == 0 &&
-                        bufferIter->second->mTransactionCount == 0) {
-                    // TODO: handle freebuffer insert fail
-                    if (!bufferIter->second->mInvalidated) {
-                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                        mFreeBuffers.insert(bufferId);
-                    } else {
-                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
-                        mBuffers.erase(bufferIter);
-                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
-                    }
-                }
-            }
-        }
-        mUsingBuffers.erase(buffers);
-    }
-
-    // Cleaning transactions
-    auto pending = mPendingTransactions.find(connectionId);
-    if (pending != mPendingTransactions.end()) {
-        for (const TransactionId& transactionId : pending->second) {
-            auto iter = mTransactions.find(transactionId);
-            if (iter != mTransactions.end()) {
-                if (!iter->second->mSenderValidated) {
-                    mCompletedTransactions.insert(transactionId);
-                }
-                BufferId bufferId = iter->second->mBufferId;
-                auto bufferIter = mBuffers.find(bufferId);
-                bufferIter->second->mTransactionCount--;
-                if (bufferIter->second->mOwnerCount == 0 &&
-                    bufferIter->second->mTransactionCount == 0) {
-                    // TODO: handle freebuffer insert fail
-                    if (!bufferIter->second->mInvalidated) {
-                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                        mFreeBuffers.insert(bufferId);
-                    } else {
-                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
-                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
-                        mBuffers.erase(bufferIter);
-                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
-                    }
-                }
-                mTransactions.erase(iter);
-            }
-        }
-    }
-    mConnectionIds.erase(connectionId);
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::getFreeBuffer(
-        const std::shared_ptr<BufferPoolAllocator> &allocator,
-        const std::vector<uint8_t> &params, BufferId *pId,
-        const native_handle_t** handle) {
-    auto bufferIt = mFreeBuffers.begin();
-    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
-        BufferId bufferId = *bufferIt;
-        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
-            break;
-        }
-    }
-    if (bufferIt != mFreeBuffers.end()) {
-        BufferId id = *bufferIt;
-        mFreeBuffers.erase(bufferIt);
-        mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
-        *handle = mBuffers[id]->handle();
-        *pId = id;
-        ALOGV("recycle a buffer %u %p", id, *handle);
-        return true;
-    }
-    return false;
-}
-
-ResultStatus Accessor::Impl::BufferPool::addNewBuffer(
-        const std::shared_ptr<BufferPoolAllocation> &alloc,
-        const size_t allocSize,
-        const std::vector<uint8_t> &params,
-        BufferId *pId,
-        const native_handle_t** handle) {
-
-    BufferId bufferId = mSeq++;
-    if (mSeq == Connection::SYNC_BUFFERID) {
-        mSeq = 0;
-    }
-    std::unique_ptr<InternalBuffer> buffer =
-            std::make_unique<InternalBuffer>(
-                    bufferId, alloc, allocSize, params);
-    if (buffer) {
-        auto res = mBuffers.insert(std::make_pair(
-                bufferId, std::move(buffer)));
-        if (res.second) {
-            mStats.onBufferAllocated(allocSize);
-            *handle = alloc->handle();
-            *pId = bufferId;
-            return ResultStatus::OK;
-        }
-    }
-    return ResultStatus::NO_MEMORY;
-}
-
-void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
-    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs ||
-            mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
-        mLastCleanUpUs = mTimestampUs;
-        if (mTimestampUs > mLastLogUs + kLogDurationUs ||
-                mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
-            mLastLogUs = mTimestampUs;
-            ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
-                  "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
-                  "%zu/%zu (fetch/transfer)",
-                  this, mStats.mBuffersCached, mStats.mSizeCached,
-                  mStats.mBuffersInUse, mStats.mSizeInUse,
-                  mStats.mTotalRecycles, mStats.mTotalAllocations,
-                  mStats.mTotalFetches, mStats.mTotalTransfers);
-        }
-        for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
-            if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
-                    (mStats.mSizeCached < kMinAllocBytesForEviction ||
-                     mBuffers.size() < kMinBufferCountForEviction)) {
-                break;
-            }
-            auto it = mBuffers.find(*freeIt);
-            if (it != mBuffers.end() &&
-                    it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
-                mStats.onBufferEvicted(it->second->mAllocSize);
-                mBuffers.erase(it);
-                freeIt = mFreeBuffers.erase(freeIt);
-            } else {
-                ++freeIt;
-                ALOGW("bufferpool2 inconsistent!");
-            }
-        }
-    }
-}
-
-void Accessor::Impl::BufferPool::invalidate(
-        bool needsAck, BufferId from, BufferId to,
-        const std::shared_ptr<Accessor::Impl> &impl) {
-    for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
-        if (isBufferInRange(from, to, *freeIt)) {
-            auto it = mBuffers.find(*freeIt);
-            if (it != mBuffers.end() &&
-                it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
-                mStats.onBufferEvicted(it->second->mAllocSize);
-                mBuffers.erase(it);
-                freeIt = mFreeBuffers.erase(freeIt);
-                continue;
-            } else {
-                ALOGW("bufferpool2 inconsistent!");
-            }
-        }
-        ++freeIt;
-    }
-
-    size_t left = 0;
-    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
-        if (isBufferInRange(from, to, it->first)) {
-            it->second->invalidate();
-            ++left;
-        }
-    }
-    mInvalidation.onInvalidationRequest(needsAck, from, to, left, mInvalidationChannel, impl);
-}
-
-void Accessor::Impl::BufferPool::flush(const std::shared_ptr<Accessor::Impl> &impl) {
-    BufferId from = mStartSeq;
-    BufferId to = mSeq;
-    mStartSeq = mSeq;
-    // TODO: needsAck params 
-    ALOGV("buffer invalidation request bp:%u %u %u", mInvalidation.mId, from, to);
-    if (from != to) {
-        invalidate(true, from, to, impl);
-    }
-}
-
-void Accessor::Impl::invalidatorThread(
-            std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> &accessors,
-            std::mutex &mutex,
-            std::condition_variable &cv,
-            bool &ready) {
-    constexpr uint32_t NUM_SPIN_TO_INCREASE_SLEEP = 1024;
-    constexpr uint32_t NUM_SPIN_TO_LOG = 1024*8;
-    constexpr useconds_t MAX_SLEEP_US = 10000;
-    uint32_t numSpin = 0;
-    useconds_t sleepUs = 1;
-
-    while(true) {
-        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> copied;
-        {
-            std::unique_lock<std::mutex> lock(mutex);
-            if (!ready) {
-                numSpin = 0;
-                sleepUs = 1;
-                cv.wait(lock);
-            }
-            copied.insert(accessors.begin(), accessors.end());
-        }
-        std::list<ConnectionId> erased;
-        for (auto it = copied.begin(); it != copied.end(); ++it) {
-            const std::shared_ptr<Accessor::Impl> impl = it->second.lock();
-            if (!impl) {
-                erased.push_back(it->first);
-            } else {
-                impl->handleInvalidateAck();
-            }
-        }
-        {
-            std::unique_lock<std::mutex> lock(mutex);
-            for (auto it = erased.begin(); it != erased.end(); ++it) {
-                accessors.erase(*it);
-            }
-            if (accessors.size() == 0) {
-                ready = false;
-            } else {
-                // TODO Use an efficient way to wait over FMQ.
-                // N.B. Since there is not a efficient way to wait over FMQ,
-                // polling over the FMQ is the current way to prevent draining
-                // CPU.
-                lock.unlock();
-                ++numSpin;
-                if (numSpin % NUM_SPIN_TO_INCREASE_SLEEP == 0 &&
-                    sleepUs < MAX_SLEEP_US) {
-                    sleepUs *= 10;
-                }
-                if (numSpin % NUM_SPIN_TO_LOG == 0) {
-                    ALOGW("invalidator thread spinning");
-                }
-                ::usleep(sleepUs);
-            }
-        }
-    }
-}
-
-Accessor::Impl::AccessorInvalidator::AccessorInvalidator() : mReady(false) {
-    std::thread invalidator(
-            invalidatorThread,
-            std::ref(mAccessors),
-            std::ref(mMutex),
-            std::ref(mCv),
-            std::ref(mReady));
-    invalidator.detach();
-}
-
-void Accessor::Impl::AccessorInvalidator::addAccessor(
-        uint32_t accessorId, const std::weak_ptr<Accessor::Impl> &impl) {
-    bool notify = false;
-    std::unique_lock<std::mutex> lock(mMutex);
-    if (mAccessors.find(accessorId) == mAccessors.end()) {
-        if (!mReady) {
-            mReady = true;
-            notify = true;
-        }
-        mAccessors.insert(std::make_pair(accessorId, impl));
-        ALOGV("buffer invalidation added bp:%u %d", accessorId, notify);
-    }
-    lock.unlock();
-    if (notify) {
-        mCv.notify_one();
-    }
-}
-
-void Accessor::Impl::AccessorInvalidator::delAccessor(uint32_t accessorId) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    mAccessors.erase(accessorId);
-    ALOGV("buffer invalidation deleted bp:%u", accessorId);
-    if (mAccessors.size() == 0) {
-        mReady = false;
-    }
-}
-
-std::unique_ptr<Accessor::Impl::AccessorInvalidator> Accessor::Impl::sInvalidator;
-
-void Accessor::Impl::createInvalidator() {
-    if (!sInvalidator) {
-        sInvalidator = std::make_unique<Accessor::Impl::AccessorInvalidator>();
-    }
-}
-
-void Accessor::Impl::evictorThread(
-        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> &accessors,
-        std::mutex &mutex,
-        std::condition_variable &cv) {
-    std::list<const std::weak_ptr<Accessor::Impl>> evictList;
-    while (true) {
-        int expired = 0;
-        int evicted = 0;
-        {
-            nsecs_t now = systemTime();
-            std::unique_lock<std::mutex> lock(mutex);
-            if (accessors.size() == 0) {
-                cv.wait(lock);
-            }
-            auto it = accessors.begin();
-            while (it != accessors.end()) {
-                if (now > (it->second + kEvictDurationNs)) {
-                    ++expired;
-                    evictList.push_back(it->first);
-                    it = accessors.erase(it);
-                } else {
-                    ++it;
-                }
-            }
-        }
-        // evict idle accessors;
-        for (auto it = evictList.begin(); it != evictList.end(); ++it) {
-            const std::shared_ptr<Accessor::Impl> accessor = it->lock();
-            if (accessor) {
-                accessor->cleanUp(true);
-                ++evicted;
-            }
-        }
-        if (expired > 0) {
-            ALOGD("evictor expired: %d, evicted: %d", expired, evicted);
-        }
-        evictList.clear();
-        ::usleep(kEvictGranularityNs / 1000);
-    }
-}
-
-Accessor::Impl::AccessorEvictor::AccessorEvictor() {
-    std::thread evictor(
-            evictorThread,
-            std::ref(mAccessors),
-            std::ref(mMutex),
-            std::ref(mCv));
-    evictor.detach();
-}
-
-void Accessor::Impl::AccessorEvictor::addAccessor(
-        const std::weak_ptr<Accessor::Impl> &impl, nsecs_t ts) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    bool notify = mAccessors.empty();
-    auto it = mAccessors.find(impl);
-    if (it == mAccessors.end()) {
-        mAccessors.emplace(impl, ts);
-    } else {
-        it->second = ts;
-    }
-    if (notify) {
-        mCv.notify_one();
-    }
-}
-
-std::unique_ptr<Accessor::Impl::AccessorEvictor> Accessor::Impl::sEvictor;
-
-void Accessor::Impl::createEvictor() {
-    if (!sEvictor) {
-        sEvictor = std::make_unique<Accessor::Impl::AccessorEvictor>();
-    }
-}
-
-void Accessor::Impl::scheduleEvictIfNeeded() {
-    nsecs_t now = systemTime();
-
-    if (now > (mScheduleEvictTs + kEvictGranularityNs)) {
-        mScheduleEvictTs = now;
-        sEvictor->addAccessor(shared_from_this(), now);
-    }
-}
-
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/bufferpool/aidl/default/AccessorImpl.h b/media/bufferpool/aidl/default/AccessorImpl.h
deleted file mode 100644
index 3d39941..0000000
--- a/media/bufferpool/aidl/default/AccessorImpl.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2018 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_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
-
-#include <map>
-#include <set>
-#include <condition_variable>
-#include <utils/Timers.h>
-#include "Accessor.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
-
-struct InternalBuffer;
-struct TransactionStatus;
-
-/**
- * An implementation of a buffer pool accessor(or a buffer pool implementation.) */
-class Accessor::Impl
-    : public std::enable_shared_from_this<Accessor::Impl> {
-public:
-    Impl(const std::shared_ptr<BufferPoolAllocator> &allocator);
-
-    ~Impl();
-
-    ResultStatus connect(
-            const sp<Accessor> &accessor, const sp<IObserver> &observer,
-            sp<Connection> *connection,
-            ConnectionId *pConnectionId,
-            uint32_t *pMsgId,
-            const StatusDescriptor** statusDescPtr,
-            const InvalidationDescriptor** invDescPtr);
-
-    ResultStatus close(ConnectionId connectionId);
-
-    ResultStatus allocate(ConnectionId connectionId,
-                          const std::vector<uint8_t>& params,
-                          BufferId *bufferId,
-                          const native_handle_t** handle);
-
-    ResultStatus fetch(ConnectionId connectionId,
-                       TransactionId transactionId,
-                       BufferId bufferId,
-                       const native_handle_t** handle);
-
-    void flush();
-
-    void cleanUp(bool clearCache);
-
-    bool isValid();
-
-    void handleInvalidateAck();
-
-    static void createInvalidator();
-
-    static void createEvictor();
-
-private:
-    // ConnectionId = pid : (timestamp_created + seqId)
-    // in order to guarantee uniqueness for each connection
-    static uint32_t sSeqId;
-
-    const std::shared_ptr<BufferPoolAllocator> mAllocator;
-
-    nsecs_t mScheduleEvictTs;
-
-    /**
-     * Buffer pool implementation.
-     *
-     * Handles buffer status messages. Handles buffer allocation/recycling.
-     * Handles buffer transfer between buffer pool clients.
-     */
-    struct BufferPool {
-    private:
-        std::mutex mMutex;
-        int64_t mTimestampUs;
-        int64_t mLastCleanUpUs;
-        int64_t mLastLogUs;
-        BufferId mSeq;
-        BufferId mStartSeq;
-        bool mValid;
-        BufferStatusObserver mObserver;
-        BufferInvalidationChannel mInvalidationChannel;
-
-        std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
-        std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
-
-        std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
-        // Transactions completed before TRANSFER_TO message arrival.
-        // Fetch does not occur for the transactions.
-        // Only transaction id is kept for the transactions in short duration.
-        std::set<TransactionId> mCompletedTransactions;
-        // Currently active(pending) transations' status & information.
-        std::map<TransactionId, std::unique_ptr<TransactionStatus>>
-                mTransactions;
-
-        std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
-        std::set<BufferId> mFreeBuffers;
-        std::set<ConnectionId> mConnectionIds;
-
-        struct Invalidation {
-            static std::atomic<std::uint32_t> sInvSeqId;
-
-            struct Pending {
-                bool mNeedsAck;
-                uint32_t mFrom;
-                uint32_t mTo;
-                size_t mLeft;
-                const std::weak_ptr<Accessor::Impl> mImpl;
-                Pending(bool needsAck, uint32_t from, uint32_t to, size_t left,
-                        const std::shared_ptr<Accessor::Impl> &impl)
-                        : mNeedsAck(needsAck),
-                          mFrom(from),
-                          mTo(to),
-                          mLeft(left),
-                          mImpl(impl)
-                {}
-
-                bool isInvalidated(uint32_t bufferId) {
-                    return isBufferInRange(mFrom, mTo, bufferId) && --mLeft == 0;
-                }
-            };
-
-            std::list<Pending> mPendings;
-            std::map<ConnectionId, uint32_t> mAcks;
-            std::map<ConnectionId, const sp<IObserver>> mObservers;
-            uint32_t mInvalidationId;
-            uint32_t mId;
-
-            Invalidation() : mInvalidationId(0), mId(sInvSeqId.fetch_add(1)) {}
-
-            void onConnect(ConnectionId conId, const sp<IObserver> &observer);
-
-            void onClose(ConnectionId conId);
-
-            void onAck(ConnectionId conId, uint32_t msgId);
-
-            void onBufferInvalidated(
-                    BufferId bufferId,
-                    BufferInvalidationChannel &channel);
-
-            void onInvalidationRequest(
-                    bool needsAck, uint32_t from, uint32_t to, size_t left,
-                    BufferInvalidationChannel &channel,
-                    const std::shared_ptr<Accessor::Impl> &impl);
-
-            void onHandleAck(
-                    std::map<ConnectionId, const sp<IObserver>> *observers,
-                    uint32_t *invalidationId);
-        } mInvalidation;
-        /// Buffer pool statistics which tracks allocation and transfer statistics.
-        struct Stats {
-            /// Total size of allocations which are used or available to use.
-            /// (bytes or pixels)
-            size_t mSizeCached;
-            /// # of cached buffers which are used or available to use.
-            size_t mBuffersCached;
-            /// Total size of allocations which are currently used. (bytes or pixels)
-            size_t mSizeInUse;
-            /// # of currently used buffers
-            size_t mBuffersInUse;
-
-            /// # of allocations called on bufferpool. (# of fetched from BlockPool)
-            size_t mTotalAllocations;
-            /// # of allocations that were served from the cache.
-            /// (# of allocator alloc prevented)
-            size_t mTotalRecycles;
-            /// # of buffer transfers initiated.
-            size_t mTotalTransfers;
-            /// # of transfers that had to be fetched.
-            size_t mTotalFetches;
-
-            Stats()
-                : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
-                  mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
-
-            /// # of currently unused buffers
-            size_t buffersNotInUse() const {
-                ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
-                return mBuffersCached - mBuffersInUse;
-            }
-
-            /// A new buffer is allocated on an allocation request.
-            void onBufferAllocated(size_t allocSize) {
-                mSizeCached += allocSize;
-                mBuffersCached++;
-
-                mSizeInUse += allocSize;
-                mBuffersInUse++;
-
-                mTotalAllocations++;
-            }
-
-            /// A buffer is evicted and destroyed.
-            void onBufferEvicted(size_t allocSize) {
-                mSizeCached -= allocSize;
-                mBuffersCached--;
-            }
-
-            /// A buffer is recycled on an allocation request.
-            void onBufferRecycled(size_t allocSize) {
-                mSizeInUse += allocSize;
-                mBuffersInUse++;
-
-                mTotalAllocations++;
-                mTotalRecycles++;
-            }
-
-            /// A buffer is available to be recycled.
-            void onBufferUnused(size_t allocSize) {
-                mSizeInUse -= allocSize;
-                mBuffersInUse--;
-            }
-
-            /// A buffer transfer is initiated.
-            void onBufferSent() {
-                mTotalTransfers++;
-            }
-
-            /// A buffer fetch is invoked by a buffer transfer.
-            void onBufferFetched() {
-                mTotalFetches++;
-            }
-        } mStats;
-
-        bool isValid() {
-            return mValid;
-        }
-
-        void invalidate(bool needsAck, BufferId from, BufferId to,
-                        const std::shared_ptr<Accessor::Impl> &impl);
-
-        static void createInvalidator();
-
-    public:
-        /** Creates a buffer pool. */
-        BufferPool();
-
-        /** Destroys a buffer pool. */
-        ~BufferPool();
-
-        /**
-         * Processes all pending buffer status messages, and returns the result.
-         * Each status message is handled by methods with 'handle' prefix.
-         */
-        void processStatusMessages();
-
-        /**
-         * Handles a buffer being owned by a connection.
-         *
-         * @param connectionId  the id of the buffer owning connection.
-         * @param bufferId      the id of the buffer.
-         *
-         * @return {@code true} when the buffer is owned,
-         *         {@code false} otherwise.
-         */
-        bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
-
-        /**
-         * Handles a buffer being released by a connection.
-         *
-         * @param connectionId  the id of the buffer owning connection.
-         * @param bufferId      the id of the buffer.
-         *
-         * @return {@code true} when the buffer ownership is released,
-         *         {@code false} otherwise.
-         */
-        bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
-
-        /**
-         * Handles a transfer transaction start message from the sender.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when transfer_to message is acknowledged,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferTo(const BufferStatusMessage &message);
-
-        /**
-         * Handles a transfer transaction being acked by the receiver.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when transfer_from message is acknowledged,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferFrom(const BufferStatusMessage &message);
-
-        /**
-         * Handles a transfer transaction result message from the receiver.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when the exisitng transaction is finished,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferResult(const BufferStatusMessage &message);
-
-        /**
-         * Handles a connection being closed, and returns the result. All the
-         * buffers and transactions owned by the connection will be cleaned up.
-         * The related FMQ will be cleaned up too.
-         *
-         * @param connectionId  the id of the connection.
-         *
-         * @result {@code true} when the connection existed,
-         *         {@code false} otherwise.
-         */
-        bool handleClose(ConnectionId connectionId);
-
-        /**
-         * Recycles a existing free buffer if it is possible.
-         *
-         * @param allocator the buffer allocator
-         * @param params    the allocation parameters.
-         * @param pId       the id of the recycled buffer.
-         * @param handle    the native handle of the recycled buffer.
-         *
-         * @return {@code true} when a buffer is recycled, {@code false}
-         *         otherwise.
-         */
-        bool getFreeBuffer(
-                const std::shared_ptr<BufferPoolAllocator> &allocator,
-                const std::vector<uint8_t> &params,
-                BufferId *pId, const native_handle_t **handle);
-
-        /**
-         * Adds a newly allocated buffer to bufferpool.
-         *
-         * @param alloc     the newly allocated buffer.
-         * @param allocSize the size of the newly allocated buffer.
-         * @param params    the allocation parameters.
-         * @param pId       the buffer id for the newly allocated buffer.
-         * @param handle    the native handle for the newly allocated buffer.
-         *
-         * @return OK when an allocation is successfully allocated.
-         *         NO_MEMORY when there is no memory.
-         *         CRITICAL_ERROR otherwise.
-         */
-        ResultStatus addNewBuffer(
-                const std::shared_ptr<BufferPoolAllocation> &alloc,
-                const size_t allocSize,
-                const std::vector<uint8_t> &params,
-                BufferId *pId,
-                const native_handle_t **handle);
-
-        /**
-         * Processes pending buffer status messages and performs periodic cache
-         * cleaning.
-         *
-         * @param clearCache    if clearCache is true, it frees all buffers
-         *                      waiting to be recycled.
-         */
-        void cleanUp(bool clearCache = false);
-
-        /**
-         * Processes pending buffer status messages and invalidate all current
-         * free buffers. Active buffers are invalidated after being inactive.
-         */
-        void flush(const std::shared_ptr<Accessor::Impl> &impl);
-
-        friend class Accessor::Impl;
-    } mBufferPool;
-
-    struct  AccessorInvalidator {
-        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> mAccessors;
-        std::mutex mMutex;
-        std::condition_variable mCv;
-        bool mReady;
-
-        AccessorInvalidator();
-        void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor::Impl> &impl);
-        void delAccessor(uint32_t accessorId);
-    };
-
-    static std::unique_ptr<AccessorInvalidator> sInvalidator;
-
-    static void invalidatorThread(
-        std::map<uint32_t, const std::weak_ptr<Accessor::Impl>> &accessors,
-        std::mutex &mutex,
-        std::condition_variable &cv,
-        bool &ready);
-
-    struct AccessorEvictor {
-        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> mAccessors;
-        std::mutex mMutex;
-        std::condition_variable mCv;
-
-        AccessorEvictor();
-        void addAccessor(const std::weak_ptr<Accessor::Impl> &impl, nsecs_t ts);
-    };
-
-    static std::unique_ptr<AccessorEvictor> sEvictor;
-
-    static void evictorThread(
-        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> &accessors,
-        std::mutex &mutex,
-        std::condition_variable &cv);
-
-    void scheduleEvictIfNeeded();
-
-};
-
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace ufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_ACCESSORIMPL_H
diff --git a/media/bufferpool/aidl/default/Android.bp b/media/bufferpool/aidl/default/Android.bp
new file mode 100644
index 0000000..11a6163
--- /dev/null
+++ b/media/bufferpool/aidl/default/Android.bp
@@ -0,0 +1,50 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "libstagefright_aidl_bufferpool2",
+    vendor_available: true,
+    min_sdk_version: "29",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    srcs: [
+        "Accessor.cpp",
+        "BufferPool.cpp",
+        "BufferPoolClient.cpp",
+        "BufferStatus.cpp",
+        "ClientManager.cpp",
+        "Connection.cpp",
+        "Observer.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    export_shared_lib_headers: [
+        "libfmq",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    double_loadable: true,
+    cflags: [
+        "-DBUFFERPOOL_CLONE_HANDLES",
+    ],
+}
diff --git a/media/bufferpool/aidl/default/BufferPool.cpp b/media/bufferpool/aidl/default/BufferPool.cpp
new file mode 100644
index 0000000..ed4574f
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.cpp
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2022 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 "AidlBufferPool"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+#include "Accessor.h"
+#include "BufferPool.h"
+#include "Connection.h"
+#include "DataHelper.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+    static constexpr int64_t kCleanUpDurationMs = 500; // 0.5 sec
+    static constexpr int64_t kLogDurationMs = 5000; // 5 secs
+
+    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
+    static constexpr size_t kMinBufferCountForEviction = 25;
+    static constexpr size_t kMaxUnusedBufferCount = 64;
+    static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
+}
+
+BufferPool::BufferPool()
+    : mTimestampMs(::android::elapsedRealtime()),
+      mLastCleanUpMs(mTimestampMs),
+      mLastLogMs(mTimestampMs),
+      mSeq(0),
+      mStartSeq(0) {
+    mValid = mInvalidationChannel.isValid();
+}
+
+
+// Statistics helper
+template<typename T, typename S>
+int percentage(T base, S total) {
+    return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
+}
+
+std::atomic<std::uint32_t> BufferPool::Invalidation::sInvSeqId(0);
+
+BufferPool::~BufferPool() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    ALOGD("Destruction - bufferpool2 %p "
+          "cached: %zu/%zuM, %zu/%d%% in use; "
+          "allocs: %zu, %d%% recycled; "
+          "transfers: %zu, %d%% unfetched",
+          this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
+          mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
+          mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
+          mStats.mTotalTransfers,
+          percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
+}
+
+void BufferPool::Invalidation::onConnect(
+        ConnectionId conId, const std::shared_ptr<IObserver>& observer) {
+    mAcks[conId] = mInvalidationId; // starts from current invalidationId
+    mObservers.insert(std::make_pair(conId, observer));
+}
+
+void BufferPool::Invalidation::onClose(ConnectionId conId) {
+    mAcks.erase(conId);
+    mObservers.erase(conId);
+}
+
+void BufferPool::Invalidation::onAck(
+        ConnectionId conId,
+        uint32_t msgId) {
+    auto it = mAcks.find(conId);
+    if (it == mAcks.end()) {
+        ALOGW("ACK from inconsistent connection! %lld", (long long)conId);
+        return;
+    }
+    if (isMessageLater(msgId, it->second)) {
+        mAcks[conId] = msgId;
+    }
+}
+
+void BufferPool::Invalidation::onBufferInvalidated(
+        BufferId bufferId,
+        BufferInvalidationChannel &channel) {
+    for (auto it = mPendings.begin(); it != mPendings.end();) {
+        if (it->isInvalidated(bufferId)) {
+            uint32_t msgId = 0;
+            if (it->mNeedsAck) {
+                msgId = ++mInvalidationId;
+                if (msgId == 0) {
+                    // wrap happens
+                    msgId = ++mInvalidationId;
+                }
+            }
+            channel.postInvalidation(msgId, it->mFrom, it->mTo);
+            it = mPendings.erase(it);
+            continue;
+        }
+        ++it;
+    }
+}
+
+void BufferPool::Invalidation::onInvalidationRequest(
+        bool needsAck,
+        uint32_t from,
+        uint32_t to,
+        size_t left,
+        BufferInvalidationChannel &channel,
+        const std::shared_ptr<Accessor> &impl) {
+        uint32_t msgId = 0;
+    if (needsAck) {
+        msgId = ++mInvalidationId;
+        if (msgId == 0) {
+            // wrap happens
+            msgId = ++mInvalidationId;
+        }
+    }
+    ALOGV("bufferpool2 invalidation requested and queued");
+    if (left == 0) {
+        channel.postInvalidation(msgId, from, to);
+    } else {
+        ALOGV("bufferpoo2 invalidation requested and pending");
+        Pending pending(needsAck, from, to, left, impl);
+        mPendings.push_back(pending);
+    }
+    Accessor::sInvalidator->addAccessor(mId, impl);
+}
+
+void BufferPool::Invalidation::onHandleAck(
+        std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+        uint32_t *invalidationId) {
+    if (mInvalidationId != 0) {
+        *invalidationId = mInvalidationId;
+        std::set<int> deads;
+        for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
+            if (it->second != mInvalidationId) {
+                const std::shared_ptr<IObserver> observer = mObservers[it->first];
+                if (observer) {
+                    observers->emplace(it->first, observer);
+                    ALOGV("connection %lld will call observer (%u: %u)",
+                          (long long)it->first, it->second, mInvalidationId);
+                    // N.B: onMessage will be called later. ignore possibility of
+                    // onMessage# oneway call being lost.
+                    it->second = mInvalidationId;
+                } else {
+                    ALOGV("bufferpool2 observer died %lld", (long long)it->first);
+                    deads.insert(it->first);
+                }
+            }
+        }
+        if (deads.size() > 0) {
+            for (auto it = deads.begin(); it != deads.end(); ++it) {
+                onClose(*it);
+            }
+        }
+    }
+    if (mPendings.size() == 0) {
+        // All invalidation Ids are synced and no more pending invalidations.
+        Accessor::sInvalidator->delAccessor(mId);
+    }
+}
+
+bool BufferPool::handleOwnBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+
+    bool added = insert(&mUsingBuffers, connectionId, bufferId);
+    if (added) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount++;
+    }
+    insert(&mUsingConnections, bufferId, connectionId);
+    return added;
+}
+
+bool BufferPool::handleReleaseBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
+    if (deleted) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount--;
+        if (iter->second->mOwnerCount == 0 &&
+                iter->second->mTransactionCount == 0) {
+            if (!iter->second->mInvalidated) {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mFreeBuffers.insert(bufferId);
+            } else {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mStats.onBufferEvicted(iter->second->mAllocSize);
+                mBuffers.erase(iter);
+                mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+            }
+        }
+    }
+    erase(&mUsingConnections, bufferId, connectionId);
+    ALOGV("release buffer %u : %d", bufferId, deleted);
+    return deleted;
+}
+
+bool BufferPool::handleTransferTo(const BufferStatusMessage &message) {
+    auto completed = mCompletedTransactions.find(
+            message.transactionId);
+    if (completed != mCompletedTransactions.end()) {
+        // already completed
+        mCompletedTransactions.erase(completed);
+        return true;
+    }
+    // the buffer should exist and be owned.
+    auto bufferIter = mBuffers.find(message.bufferId);
+    if (bufferIter == mBuffers.end() ||
+            !contains(&mUsingBuffers, message.connectionId, FromAidl(message.bufferId))) {
+        return false;
+    }
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        // transfer_from was received earlier.
+        found->second->mSender = message.connectionId;
+        found->second->mSenderValidated = true;
+        return true;
+    }
+    if (mConnectionIds.find(message.targetConnectionId) == mConnectionIds.end()) {
+        // N.B: it could be fake or receive connection already closed.
+        ALOGD("bufferpool2 %p receiver connection %lld is no longer valid",
+              this, (long long)message.targetConnectionId);
+        return false;
+    }
+    mStats.onBufferSent();
+    mTransactions.insert(std::make_pair(
+            message.transactionId,
+            std::make_unique<TransactionStatus>(message, mTimestampMs)));
+    insert(&mPendingTransactions, message.targetConnectionId,
+           FromAidl(message.transactionId));
+    bufferIter->second->mTransactionCount++;
+    return true;
+}
+
+bool BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found == mTransactions.end()) {
+        // TODO: is it feasible to check ownership here?
+        mStats.onBufferSent();
+        mTransactions.insert(std::make_pair(
+                message.transactionId,
+                std::make_unique<TransactionStatus>(message, mTimestampMs)));
+        insert(&mPendingTransactions, message.connectionId,
+               FromAidl(message.transactionId));
+        auto bufferIter = mBuffers.find(message.bufferId);
+        bufferIter->second->mTransactionCount++;
+    } else {
+        if (message.connectionId == found->second->mReceiver) {
+            found->second->mStatus = BufferStatus::TRANSFER_FROM;
+        }
+    }
+    return true;
+}
+
+bool BufferPool::handleTransferResult(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        bool deleted = erase(&mPendingTransactions, message.connectionId,
+                             FromAidl(message.transactionId));
+        if (deleted) {
+            if (!found->second->mSenderValidated) {
+                mCompletedTransactions.insert(message.transactionId);
+            }
+            auto bufferIter = mBuffers.find(message.bufferId);
+            if (message.status == BufferStatus::TRANSFER_OK) {
+                handleOwnBuffer(message.connectionId, message.bufferId);
+            }
+            bufferIter->second->mTransactionCount--;
+            if (bufferIter->second->mOwnerCount == 0
+                && bufferIter->second->mTransactionCount == 0) {
+                if (!bufferIter->second->mInvalidated) {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mFreeBuffers.insert(message.bufferId);
+                } else {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                    mBuffers.erase(bufferIter);
+                    mInvalidation.onBufferInvalidated(message.bufferId, mInvalidationChannel);
+                }
+            }
+            mTransactions.erase(found);
+        }
+        ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
+              message.bufferId, deleted);
+        return deleted;
+    }
+    ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
+          message.bufferId);
+    return false;
+}
+
+void BufferPool::processStatusMessages() {
+    std::vector<BufferStatusMessage> messages;
+    mObserver.getBufferStatusChanges(messages);
+    mTimestampMs = ::android::elapsedRealtime();
+    for (BufferStatusMessage& message: messages) {
+        bool ret = false;
+        switch (message.status) {
+            case BufferStatus::NOT_USED:
+                ret = handleReleaseBuffer(
+                        message.connectionId, message.bufferId);
+                break;
+            case BufferStatus::USED:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_TO:
+                ret = handleTransferTo(message);
+                break;
+            case BufferStatus::TRANSFER_FROM:
+                ret = handleTransferFrom(message);
+                break;
+            case BufferStatus::TRANSFER_TIMEOUT:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_LOST:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_FETCH:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_OK:
+            case BufferStatus::TRANSFER_ERROR:
+                ret = handleTransferResult(message);
+                break;
+            case BufferStatus::INVALIDATION_ACK:
+                mInvalidation.onAck(message.connectionId, message.bufferId);
+                ret = true;
+                break;
+        }
+        if (ret == false) {
+            ALOGW("buffer status message processing failure - message : %d connection : %lld",
+                  message.status, (long long)message.connectionId);
+        }
+    }
+    messages.clear();
+}
+
+bool BufferPool::handleClose(ConnectionId connectionId) {
+    // Cleaning buffers
+    auto buffers = mUsingBuffers.find(connectionId);
+    if (buffers != mUsingBuffers.end()) {
+        for (const BufferId& bufferId : buffers->second) {
+            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
+            if (deleted) {
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mOwnerCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                        bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+            }
+        }
+        mUsingBuffers.erase(buffers);
+    }
+
+    // Cleaning transactions
+    auto pending = mPendingTransactions.find(connectionId);
+    if (pending != mPendingTransactions.end()) {
+        for (const TransactionId& transactionId : pending->second) {
+            auto iter = mTransactions.find(transactionId);
+            if (iter != mTransactions.end()) {
+                if (!iter->second->mSenderValidated) {
+                    mCompletedTransactions.insert(transactionId);
+                }
+                BufferId bufferId = iter->second->mBufferId;
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mTransactionCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                    bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+                mTransactions.erase(iter);
+            }
+        }
+    }
+    mConnectionIds.erase(connectionId);
+    return true;
+}
+
+bool BufferPool::getFreeBuffer(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        const std::vector<uint8_t> &params, BufferId *pId,
+        const native_handle_t** handle) {
+    auto bufferIt = mFreeBuffers.begin();
+    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
+        BufferId bufferId = *bufferIt;
+        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
+            break;
+        }
+    }
+    if (bufferIt != mFreeBuffers.end()) {
+        BufferId id = *bufferIt;
+        mFreeBuffers.erase(bufferIt);
+        mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
+        *handle = mBuffers[id]->handle();
+        *pId = id;
+        ALOGV("recycle a buffer %u %p", id, *handle);
+        return true;
+    }
+    return false;
+}
+
+BufferPoolStatus BufferPool::addNewBuffer(
+        const std::shared_ptr<BufferPoolAllocation> &alloc,
+        const size_t allocSize,
+        const std::vector<uint8_t> &params,
+        BufferId *pId,
+        const native_handle_t** handle) {
+
+    BufferId bufferId = mSeq++;
+    if (mSeq == Connection::SYNC_BUFFERID) {
+        mSeq = 0;
+    }
+    std::unique_ptr<InternalBuffer> buffer =
+            std::make_unique<InternalBuffer>(
+                    bufferId, alloc, allocSize, params);
+    if (buffer) {
+        auto res = mBuffers.insert(std::make_pair(
+                bufferId, std::move(buffer)));
+        if (res.second) {
+            mStats.onBufferAllocated(allocSize);
+            *handle = alloc->handle();
+            *pId = bufferId;
+            return ResultStatus::OK;
+        }
+    }
+    return ResultStatus::NO_MEMORY;
+}
+
+void BufferPool::cleanUp(bool clearCache) {
+    if (clearCache || mTimestampMs > mLastCleanUpMs + kCleanUpDurationMs ||
+            mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+        mLastCleanUpMs = mTimestampMs;
+        if (mTimestampMs > mLastLogMs + kLogDurationMs ||
+                mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+            mLastLogMs = mTimestampMs;
+            ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
+                  "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
+                  "%zu/%zu (fetch/transfer)",
+                  this, mStats.mBuffersCached, mStats.mSizeCached,
+                  mStats.mBuffersInUse, mStats.mSizeInUse,
+                  mStats.mTotalRecycles, mStats.mTotalAllocations,
+                  mStats.mTotalFetches, mStats.mTotalTransfers);
+        }
+        for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+            if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
+                    (mStats.mSizeCached < kMinAllocBytesForEviction ||
+                     mBuffers.size() < kMinBufferCountForEviction)) {
+                break;
+            }
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                    it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+            } else {
+                ++freeIt;
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+    }
+}
+
+void BufferPool::invalidate(
+        bool needsAck, BufferId from, BufferId to,
+        const std::shared_ptr<Accessor> &impl) {
+    for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+        if (isBufferInRange(from, to, *freeIt)) {
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+                continue;
+            } else {
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+        ++freeIt;
+    }
+
+    size_t left = 0;
+    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
+        if (isBufferInRange(from, to, it->first)) {
+            it->second->invalidate();
+            ++left;
+        }
+    }
+    mInvalidation.onInvalidationRequest(needsAck, from, to, left, mInvalidationChannel, impl);
+}
+
+void BufferPool::flush(const std::shared_ptr<Accessor> &impl) {
+    BufferId from = mStartSeq;
+    BufferId to = mSeq;
+    mStartSeq = mSeq;
+    // TODO: needsAck params
+    ALOGV("buffer invalidation request bp:%u %u %u", mInvalidation.mId, from, to);
+    if (from != to) {
+        invalidate(true, from, to, impl);
+    }
+}
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPool.h b/media/bufferpool/aidl/default/BufferPool.h
new file mode 100644
index 0000000..1529a53
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <map>
+#include <set>
+#include <vector>
+#include <mutex>
+#include <condition_variable>
+#include <utils/Timers.h>
+
+#include "BufferStatus.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using BufferStatus = aidl::android::hardware::media::bufferpool2::BufferStatus;
+using BufferStatusMessage = aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+
+struct Accessor;
+struct InternalBuffer;
+struct TransactionStatus;
+
+/**
+ * Buffer pool implementation.
+ *
+ * Handles buffer status messages. Handles buffer allocation/recycling.
+ * Handles buffer transfer between buffer pool clients.
+ */
+struct BufferPool {
+private:
+    std::mutex mMutex;
+    int64_t mTimestampMs;
+    int64_t mLastCleanUpMs;
+    int64_t mLastLogMs;
+    BufferId mSeq;
+    BufferId mStartSeq;
+    bool mValid;
+    BufferStatusObserver mObserver;
+    BufferInvalidationChannel mInvalidationChannel;
+
+    std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
+    std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
+
+    std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
+    // Transactions completed before TRANSFER_TO message arrival.
+    // Fetch does not occur for the transactions.
+    // Only transaction id is kept for the transactions in short duration.
+    std::set<TransactionId> mCompletedTransactions;
+    // Currently active(pending) transations' status & information.
+    std::map<TransactionId, std::unique_ptr<TransactionStatus>>
+            mTransactions;
+
+    std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
+    std::set<BufferId> mFreeBuffers;
+    std::set<ConnectionId> mConnectionIds;
+
+    struct Invalidation {
+        static std::atomic<std::uint32_t> sInvSeqId;
+
+        struct Pending {
+            bool mNeedsAck;
+            uint32_t mFrom;
+            uint32_t mTo;
+            size_t mLeft;
+            const std::weak_ptr<Accessor> mImpl;
+            Pending(bool needsAck, uint32_t from, uint32_t to, size_t left,
+                    const std::shared_ptr<Accessor> &impl)
+                    : mNeedsAck(needsAck),
+                      mFrom(from),
+                      mTo(to),
+                      mLeft(left),
+                      mImpl(impl)
+            {}
+
+            bool isInvalidated(uint32_t bufferId) {
+                return isBufferInRange(mFrom, mTo, bufferId) && --mLeft == 0;
+            }
+        };
+
+        std::list<Pending> mPendings;
+        std::map<ConnectionId, uint32_t> mAcks;
+        std::map<ConnectionId, const std::shared_ptr<IObserver>> mObservers;
+        uint32_t mInvalidationId;
+        uint32_t mId;
+
+        Invalidation() : mInvalidationId(0), mId(sInvSeqId.fetch_add(1)) {}
+
+        void onConnect(ConnectionId conId, const std::shared_ptr<IObserver> &observer);
+
+        void onClose(ConnectionId conId);
+
+        void onAck(ConnectionId conId, uint32_t msgId);
+
+        void onBufferInvalidated(
+                BufferId bufferId,
+                BufferInvalidationChannel &channel);
+
+        void onInvalidationRequest(
+                bool needsAck, uint32_t from, uint32_t to, size_t left,
+                BufferInvalidationChannel &channel,
+                const std::shared_ptr<Accessor> &impl);
+
+        void onHandleAck(
+                std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+                uint32_t *invalidationId);
+    } mInvalidation;
+    /// Buffer pool statistics which tracks allocation and transfer statistics.
+    struct Stats {
+        /// Total size of allocations which are used or available to use.
+        /// (bytes or pixels)
+        size_t mSizeCached;
+        /// # of cached buffers which are used or available to use.
+        size_t mBuffersCached;
+        /// Total size of allocations which are currently used. (bytes or pixels)
+        size_t mSizeInUse;
+        /// # of currently used buffers
+        size_t mBuffersInUse;
+
+        /// # of allocations called on bufferpool. (# of fetched from BlockPool)
+        size_t mTotalAllocations;
+        /// # of allocations that were served from the cache.
+        /// (# of allocator alloc prevented)
+        size_t mTotalRecycles;
+        /// # of buffer transfers initiated.
+        size_t mTotalTransfers;
+        /// # of transfers that had to be fetched.
+        size_t mTotalFetches;
+
+        Stats()
+            : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
+              mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
+
+        /// # of currently unused buffers
+        size_t buffersNotInUse() const {
+            ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
+            return mBuffersCached - mBuffersInUse;
+        }
+
+        /// A new buffer is allocated on an allocation request.
+        void onBufferAllocated(size_t allocSize) {
+            mSizeCached += allocSize;
+            mBuffersCached++;
+
+            mSizeInUse += allocSize;
+            mBuffersInUse++;
+
+            mTotalAllocations++;
+        }
+
+        /// A buffer is evicted and destroyed.
+        void onBufferEvicted(size_t allocSize) {
+            mSizeCached -= allocSize;
+            mBuffersCached--;
+        }
+
+        /// A buffer is recycled on an allocation request.
+        void onBufferRecycled(size_t allocSize) {
+            mSizeInUse += allocSize;
+            mBuffersInUse++;
+
+            mTotalAllocations++;
+            mTotalRecycles++;
+        }
+
+        /// A buffer is available to be recycled.
+        void onBufferUnused(size_t allocSize) {
+            mSizeInUse -= allocSize;
+            mBuffersInUse--;
+        }
+
+        /// A buffer transfer is initiated.
+        void onBufferSent() {
+            mTotalTransfers++;
+        }
+
+        /// A buffer fetch is invoked by a buffer transfer.
+        void onBufferFetched() {
+            mTotalFetches++;
+        }
+    } mStats;
+
+    bool isValid() {
+        return mValid;
+    }
+
+    void invalidate(bool needsAck, BufferId from, BufferId to,
+                    const std::shared_ptr<Accessor> &impl);
+
+    static void createInvalidator();
+
+public:
+    /** Creates a buffer pool. */
+    BufferPool();
+
+    /** Destroys a buffer pool. */
+    ~BufferPool();
+
+    /**
+     * Processes all pending buffer status messages, and returns the result.
+     * Each status message is handled by methods with 'handle' prefix.
+     */
+    void processStatusMessages();
+
+    /**
+     * Handles a buffer being owned by a connection.
+     *
+     * @param connectionId  the id of the buffer owning connection.
+     * @param bufferId      the id of the buffer.
+     *
+     * @return {@code true} when the buffer is owned,
+     *         {@code false} otherwise.
+     */
+    bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
+
+    /**
+     * Handles a buffer being released by a connection.
+     *
+     * @param connectionId  the id of the buffer owning connection.
+     * @param bufferId      the id of the buffer.
+     *
+     * @return {@code true} when the buffer ownership is released,
+     *         {@code false} otherwise.
+     */
+    bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
+
+    /**
+     * Handles a transfer transaction start message from the sender.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when transfer_to message is acknowledged,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferTo(const BufferStatusMessage &message);
+
+    /**
+     * Handles a transfer transaction being acked by the receiver.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when transfer_from message is acknowledged,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferFrom(const BufferStatusMessage &message);
+
+    /**
+     * Handles a transfer transaction result message from the receiver.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when the existing transaction is finished,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferResult(const BufferStatusMessage &message);
+
+    /**
+     * Handles a connection being closed, and returns the result. All the
+     * buffers and transactions owned by the connection will be cleaned up.
+     * The related FMQ will be cleaned up too.
+     *
+     * @param connectionId  the id of the connection.
+     *
+     * @result {@code true} when the connection existed,
+     *         {@code false} otherwise.
+     */
+    bool handleClose(ConnectionId connectionId);
+
+    /**
+     * Recycles a existing free buffer if it is possible.
+     *
+     * @param allocator the buffer allocator
+     * @param params    the allocation parameters.
+     * @param pId       the id of the recycled buffer.
+     * @param handle    the native handle of the recycled buffer.
+     *
+     * @return {@code true} when a buffer is recycled, {@code false}
+     *         otherwise.
+     */
+    bool getFreeBuffer(
+            const std::shared_ptr<BufferPoolAllocator> &allocator,
+            const std::vector<uint8_t> &params,
+            BufferId *pId, const native_handle_t **handle);
+
+    /**
+     * Adds a newly allocated buffer to bufferpool.
+     *
+     * @param alloc     the newly allocated buffer.
+     * @param allocSize the size of the newly allocated buffer.
+     * @param params    the allocation parameters.
+     * @param pId       the buffer id for the newly allocated buffer.
+     * @param handle    the native handle for the newly allocated buffer.
+     *
+     * @return OK when an allocation is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus addNewBuffer(
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &params,
+            BufferId *pId,
+            const native_handle_t **handle);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache
+     * cleaning.
+     *
+     * @param clearCache    if clearCache is true, it frees all buffers
+     *                      waiting to be recycled.
+     */
+    void cleanUp(bool clearCache = false);
+
+    /**
+     * Processes pending buffer status messages and invalidate all current
+     * free buffers. Active buffers are invalidated after being inactive.
+     */
+    void flush(const std::shared_ptr<Accessor> &impl);
+
+    friend struct Accessor;
+};
+
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index cda23ff..e9777d8 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,33 +14,37 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "BufferPoolClient"
+#define LOG_TAG "AidlBufferPoolCli"
 //#define LOG_NDEBUG 0
 
 #include <thread>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <utils/Log.h>
 #include "BufferPoolClient.h"
+#include "Accessor.h"
 #include "Connection.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-static constexpr int64_t kReceiveTimeoutUs = 2000000; // 2s
+using aidl::android::hardware::media::bufferpool2::IConnection;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+static constexpr int64_t kReceiveTimeoutMs = 2000; // 2s
 static constexpr int kPostMaxRetry = 3;
-static constexpr int kCacheTtlUs = 1000000; // TODO: tune
+static constexpr int kCacheTtlMs = 1000;
 static constexpr size_t kMaxCachedBufferCount = 64;
 static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
 
 class BufferPoolClient::Impl
         : public std::enable_shared_from_this<BufferPoolClient::Impl> {
 public:
-    explicit Impl(const sp<Accessor> &accessor, const sp<IObserver> &observer);
+    explicit Impl(const std::shared_ptr<Accessor> &accessor,
+                  const std::shared_ptr<IObserver> &observer);
 
-    explicit Impl(const sp<IAccessor> &accessor, const sp<IObserver> &observer);
+    explicit Impl(const std::shared_ptr<IAccessor> &accessor,
+                  const std::shared_ptr<IObserver> &observer);
 
     bool isValid() {
         return mValid;
@@ -54,35 +58,35 @@
         return mConnectionId;
     }
 
-    sp<IAccessor> &getAccessor() {
+    std::shared_ptr<IAccessor> &getAccessor() {
         return mAccessor;
     }
 
-    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+    bool isActive(int64_t *lastTransactionMs, bool clearCache);
 
     void receiveInvalidation(uint32_t msgID);
 
-    ResultStatus flush();
+    BufferPoolStatus flush();
 
-    ResultStatus allocate(const std::vector<uint8_t> &params,
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
                           native_handle_t **handle,
                           std::shared_ptr<BufferPoolData> *buffer);
 
-    ResultStatus receive(
+    BufferPoolStatus receive(
             TransactionId transactionId, BufferId bufferId,
-            int64_t timestampUs,
+            int64_t timestampMs,
             native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
 
     void postBufferRelease(BufferId bufferId);
 
     bool postSend(
             BufferId bufferId, ConnectionId receiver,
-            TransactionId *transactionId, int64_t *timestampUs);
+            TransactionId *transactionId, int64_t *timestampMs);
 private:
 
     bool postReceive(
             BufferId bufferId, TransactionId transactionId,
-            int64_t timestampUs);
+            int64_t timestampMs);
 
     bool postReceiveResult(
             BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
@@ -97,11 +101,11 @@
 
     void invalidateRange(BufferId from, BufferId to);
 
-    ResultStatus allocateBufferHandle(
+    BufferPoolStatus allocateBufferHandle(
             const std::vector<uint8_t>& params, BufferId *bufferId,
             native_handle_t **handle);
 
-    ResultStatus fetchBufferHandle(
+    BufferPoolStatus fetchBufferHandle(
             TransactionId transactionId, BufferId bufferId,
             native_handle_t **handle);
 
@@ -110,12 +114,12 @@
 
     bool mLocal;
     bool mValid;
-    sp<IAccessor> mAccessor;
-    sp<Connection> mLocalConnection;
-    sp<IConnection> mRemoteConnection;
+    std::shared_ptr<IAccessor> mAccessor;
+    std::shared_ptr<Connection> mLocalConnection;
+    std::shared_ptr<IConnection> mRemoteConnection;
     uint32_t mSeqId;
     ConnectionId mConnectionId;
-    int64_t mLastEvictCacheUs;
+    int64_t mLastEvictCacheMs;
     std::unique_ptr<BufferInvalidationListener> mInvalidationListener;
 
     // CachedBuffers
@@ -125,18 +129,19 @@
         std::condition_variable mCreateCv;
         std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
         int mActive;
-        int64_t mLastChangeUs;
+        int64_t mLastChangeMs;
 
-        BufferCache() : mCreating(false), mActive(0), mLastChangeUs(getTimestampNow()) {}
+        BufferCache() : mCreating(false), mActive(0),
+                mLastChangeMs(::android::elapsedRealtime()) {}
 
         void incActive_l() {
             ++mActive;
-            mLastChangeUs = getTimestampNow();
+            mLastChangeMs = ::android::elapsedRealtime();
         }
 
         void decActive_l() {
             --mActive;
-            mLastChangeUs = getTimestampNow();
+            mLastChangeMs = ::android::elapsedRealtime();
         }
 
         int cachedBufferCount() const {
@@ -147,7 +152,6 @@
     // FMQ - release notifier
     struct ReleaseCache {
         std::mutex mLock;
-        // TODO: use only one list?(using one list may dealy sending messages?)
         std::list<BufferId> mReleasingIds;
         std::list<BufferId> mReleasedIds;
         uint32_t mInvalidateId; // TODO: invalidation ACK to bufferpool
@@ -158,7 +162,7 @@
     } mReleasing;
 
     // This lock is held during synchronization from remote side.
-    // In order to minimize remote calls and locking durtaion, this lock is held
+    // In order to minimize remote calls and locking duration, this lock is held
     // by best effort approach using try_lock().
     std::mutex mRemoteSyncLock;
 };
@@ -181,7 +185,7 @@
 
 struct BufferPoolClient::Impl::ClientBuffer {
 private:
-    int64_t mExpireUs;
+    int64_t mExpireMs;
     bool mHasCache;
     ConnectionId mConnectionId;
     BufferId mId;
@@ -189,7 +193,7 @@
     std::weak_ptr<BufferPoolData> mCache;
 
     void updateExpire() {
-        mExpireUs = getTimestampNow() + kCacheTtlUs;
+        mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
     }
 
 public:
@@ -197,7 +201,7 @@
             ConnectionId connectionId, BufferId id, native_handle_t *handle)
             : mHasCache(false), mConnectionId(connectionId),
               mId(id), mHandle(handle) {
-        mExpireUs = getTimestampNow() + kCacheTtlUs;
+        mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
     }
 
     ~ClientBuffer() {
@@ -212,8 +216,8 @@
     }
 
     bool expire() const {
-        int64_t now = getTimestampNow();
-        return now >= mExpireUs;
+        int64_t now = ::android::elapsedRealtime();
+        return now >= mExpireMs;
     }
 
     bool hasCache() const {
@@ -265,20 +269,21 @@
     }
 };
 
-BufferPoolClient::Impl::Impl(const sp<Accessor> &accessor, const sp<IObserver> &observer)
+BufferPoolClient::Impl::Impl(const std::shared_ptr<Accessor> &accessor,
+                             const std::shared_ptr<IObserver> &observer)
     : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
-      mLastEvictCacheUs(getTimestampNow()) {
-    const StatusDescriptor *statusDesc;
-    const InvalidationDescriptor *invDesc;
-    ResultStatus status = accessor->connect(
+      mLastEvictCacheMs(::android::elapsedRealtime()) {
+    StatusDescriptor statusDesc;
+    InvalidationDescriptor invDesc;
+    BufferPoolStatus status = accessor->connect(
             observer, true,
             &mLocalConnection, &mConnectionId, &mReleasing.mInvalidateId,
             &statusDesc, &invDesc);
     if (status == ResultStatus::OK) {
         mReleasing.mStatusChannel =
-                std::make_unique<BufferStatusChannel>(*statusDesc);
+                std::make_unique<BufferStatusChannel>(statusDesc);
         mInvalidationListener =
-                std::make_unique<BufferInvalidationListener>(*invDesc);
+                std::make_unique<BufferInvalidationListener>(invDesc);
         mValid = mReleasing.mStatusChannel &&
                 mReleasing.mStatusChannel->isValid() &&
                 mInvalidationListener &&
@@ -286,46 +291,36 @@
     }
 }
 
-BufferPoolClient::Impl::Impl(const sp<IAccessor> &accessor, const sp<IObserver> &observer)
+BufferPoolClient::Impl::Impl(const std::shared_ptr<IAccessor> &accessor,
+                             const std::shared_ptr<IObserver> &observer)
     : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
-      mLastEvictCacheUs(getTimestampNow()) {
+      mLastEvictCacheMs(::android::elapsedRealtime()) {
+    IAccessor::ConnectionInfo conInfo;
     bool valid = false;
-    sp<IConnection>& outConnection = mRemoteConnection;
-    ConnectionId& id = mConnectionId;
-    uint32_t& outMsgId = mReleasing.mInvalidateId;
-    std::unique_ptr<BufferStatusChannel>& outChannel =
-            mReleasing.mStatusChannel;
-    std::unique_ptr<BufferInvalidationListener>& outObserver =
-            mInvalidationListener;
-    Return<void> transResult = accessor->connect(
-            observer,
-            [&valid, &outConnection, &id, &outMsgId, &outChannel, &outObserver]
-            (ResultStatus status, sp<IConnection> connection,
-             ConnectionId connectionId, uint32_t msgId,
-             const StatusDescriptor& statusDesc,
-             const InvalidationDescriptor& invDesc) {
-                if (status == ResultStatus::OK) {
-                    outConnection = connection;
-                    id = connectionId;
-                    outMsgId = msgId;
-                    outChannel = std::make_unique<BufferStatusChannel>(statusDesc);
-                    outObserver = std::make_unique<BufferInvalidationListener>(invDesc);
-                    if (outChannel && outChannel->isValid() &&
-                        outObserver && outObserver->isValid()) {
-                        valid = true;
-                    }
-                }
-            });
-    mValid = transResult.isOk() && valid;
+    if(accessor->connect(observer, &conInfo).isOk()) {
+        auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
+        auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
+
+        if (channel && channel->isValid()
+            && observer && observer->isValid()) {
+            mRemoteConnection = conInfo.connection;
+            mConnectionId = conInfo.connectionId;
+            mReleasing.mInvalidateId = conInfo.msgId;
+            mReleasing.mStatusChannel = std::move(channel);
+            mInvalidationListener = std::move(observer);
+            valid = true;
+        }
+    }
+    mValid = valid;
 }
 
-bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionUs, bool clearCache) {
+bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionMs, bool clearCache) {
     bool active = false;
     {
         std::lock_guard<std::mutex> lock(mCache.mLock);
         syncReleased();
         evictCaches(clearCache);
-        *lastTransactionUs = mCache.mLastChangeUs;
+        *lastTransactionMs = mCache.mLastChangeMs;
         active = mCache.mActive > 0;
     }
     if (mValid && mLocal && mLocalConnection) {
@@ -341,7 +336,7 @@
     // TODO: evict cache required?
 }
 
-ResultStatus BufferPoolClient::Impl::flush() {
+BufferPoolStatus BufferPoolClient::Impl::flush() {
     if (!mLocal || !mLocalConnection || !mValid) {
         return ResultStatus::CRITICAL_ERROR;
     }
@@ -353,7 +348,7 @@
     }
 }
 
-ResultStatus BufferPoolClient::Impl::allocate(
+BufferPoolStatus BufferPoolClient::Impl::allocate(
         const std::vector<uint8_t> &params,
         native_handle_t **pHandle,
         std::shared_ptr<BufferPoolData> *buffer) {
@@ -363,7 +358,7 @@
     BufferId bufferId;
     native_handle_t *handle = nullptr;
     buffer->reset();
-    ResultStatus status = allocateBufferHandle(params, &bufferId, &handle);
+    BufferPoolStatus status = allocateBufferHandle(params, &bufferId, &handle);
     if (status == ResultStatus::OK) {
         if (handle) {
             std::unique_lock<std::mutex> lock(mCache.mLock);
@@ -398,20 +393,20 @@
     return status;
 }
 
-ResultStatus BufferPoolClient::Impl::receive(
-        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+BufferPoolStatus BufferPoolClient::Impl::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
         native_handle_t **pHandle,
         std::shared_ptr<BufferPoolData> *buffer) {
     if (!mValid) {
         return ResultStatus::CRITICAL_ERROR;
     }
-    if (timestampUs != 0) {
-        timestampUs += kReceiveTimeoutUs;
+    if (timestampMs != 0) {
+        timestampMs += kReceiveTimeoutMs;
     }
-    if (!postReceive(bufferId, transactionId, timestampUs)) {
+    if (!postReceive(bufferId, transactionId, timestampMs)) {
         return ResultStatus::CRITICAL_ERROR;
     }
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
     buffer->reset();
     while(1) {
         std::unique_lock<std::mutex> lock(mCache.mLock);
@@ -505,7 +500,7 @@
 // TODO: revise ad-hoc posting data structure
 bool BufferPoolClient::Impl::postSend(
         BufferId bufferId, ConnectionId receiver,
-        TransactionId *transactionId, int64_t *timestampUs) {
+        TransactionId *transactionId, int64_t *timestampMs) {
     {
         // TODO: don't need to call syncReleased every time
         std::lock_guard<std::mutex> lock(mCache.mLock);
@@ -515,7 +510,7 @@
     bool needsSync = false;
     {
         std::lock_guard<std::mutex> lock(mReleasing.mLock);
-        *timestampUs = getTimestampNow();
+        *timestampMs = ::android::elapsedRealtime();
         *transactionId = (mConnectionId << 32) | mSeqId++;
         // TODO: retry, add timeout, target?
         ret =  mReleasing.mStatusChannel->postBufferStatusMessage(
@@ -533,11 +528,11 @@
 }
 
 bool BufferPoolClient::Impl::postReceive(
-        BufferId bufferId, TransactionId transactionId, int64_t timestampUs) {
+        BufferId bufferId, TransactionId transactionId, int64_t timestampMs) {
     for (int i = 0; i < kPostMaxRetry; ++i) {
         std::unique_lock<std::mutex> lock(mReleasing.mLock);
-        int64_t now = getTimestampNow();
-        if (timestampUs == 0 || now < timestampUs) {
+        int64_t now = ::android::elapsedRealtime();
+        if (timestampMs == 0 || now < timestampMs) {
             bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
                     transactionId, bufferId, BufferStatus::TRANSFER_FROM,
                     mConnectionId, -1, mReleasing.mReleasingIds,
@@ -579,16 +574,7 @@
             needsSync = mReleasing.mStatusChannel->needsSync();
         }
         if (needsSync) {
-            TransactionId transactionId = (mConnectionId << 32);
-            BufferId bufferId = Connection::SYNC_BUFFERID;
-            Return<void> transResult = mRemoteConnection->fetch(
-                    transactionId, bufferId,
-                    []
-                    (ResultStatus outStatus, Buffer outBuffer) {
-                        (void) outStatus;
-                        (void) outBuffer;
-                    });
-            if (!transResult.isOk()) {
+            if (!mRemoteConnection->sync().isOk()) {
                 ALOGD("sync from client %lld failed: bufferpool process died.",
                       (long long)mConnectionId);
             }
@@ -616,12 +602,12 @@
                         mCache.decActive_l();
                     } else {
                         // should not happen!
-                        ALOGW("client %lld cache release status inconsitent!",
+                        ALOGW("client %lld cache release status inconsistent!",
                             (long long)mConnectionId);
                     }
                 } else {
                     // should not happen!
-                    ALOGW("client %lld cache status inconsitent!", (long long)mConnectionId);
+                    ALOGW("client %lld cache status inconsistent!", (long long)mConnectionId);
                 }
             }
             mReleasing.mReleasedIds.clear();
@@ -673,8 +659,8 @@
 
 // should have mCache.mLock
 void BufferPoolClient::Impl::evictCaches(bool clearCache) {
-    int64_t now = getTimestampNow();
-    if (now >= mLastEvictCacheUs + kCacheTtlUs ||
+    int64_t now = ::android::elapsedRealtime();
+    if (now >= mLastEvictCacheMs + kCacheTtlMs ||
             clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
         size_t evicted = 0;
         for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
@@ -688,7 +674,7 @@
         }
         ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
               (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
-        mLastEvictCacheUs = now;
+        mLastEvictCacheMs = now;
     }
 }
 
@@ -701,7 +687,7 @@
                 ALOGV("cache invalidated %lld : buffer %u",
                       (long long)mConnectionId, id);
             } else {
-                ALOGW("Inconsitent invalidation %lld : activer buffer!! %u",
+                ALOGW("Inconsistent invalidation %lld : activer buffer!! %u",
                       (long long)mConnectionId, (unsigned int)id);
             }
             break;
@@ -735,12 +721,12 @@
           (long long)mConnectionId, invalidated);
 }
 
-ResultStatus BufferPoolClient::Impl::allocateBufferHandle(
+BufferPoolStatus BufferPoolClient::Impl::allocateBufferHandle(
         const std::vector<uint8_t>& params, BufferId *bufferId,
         native_handle_t** handle) {
     if (mLocalConnection) {
         const native_handle_t* allocHandle = nullptr;
-        ResultStatus status = mLocalConnection->allocate(
+        BufferPoolStatus status = mLocalConnection->allocate(
                 params, bufferId, &allocHandle);
         if (status == ResultStatus::OK) {
             *handle = native_handle_clone(allocHandle);
@@ -753,37 +739,38 @@
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus BufferPoolClient::Impl::fetchBufferHandle(
+BufferPoolStatus BufferPoolClient::Impl::fetchBufferHandle(
         TransactionId transactionId, BufferId bufferId,
         native_handle_t **handle) {
-    sp<IConnection> connection;
+    std::shared_ptr<IConnection> connection;
     if (mLocal) {
         connection = mLocalConnection;
     } else {
         connection = mRemoteConnection;
     }
-    ResultStatus status;
-    Return<void> transResult = connection->fetch(
-            transactionId, bufferId,
-            [&status, &handle]
-            (ResultStatus outStatus, Buffer outBuffer) {
-                status = outStatus;
-                if (status == ResultStatus::OK) {
-                    *handle = native_handle_clone(
-                            outBuffer.buffer.getNativeHandle());
-                }
-            });
-    return transResult.isOk() ? status : ResultStatus::CRITICAL_ERROR;
+    std::vector<FetchInfo> infos;
+    std::vector<FetchResult> results;
+    infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
+    ndk::ScopedAStatus status = connection->fetch(infos, &results);
+    if (!status.isOk()) {
+        BufferPoolStatus svcSpecific = status.getServiceSpecificError();
+        return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
+    }
+    if (results[0].getTag() == FetchResult::buffer) {
+        *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer);
+        return ResultStatus::OK;
+    }
+    return results[0].get<FetchResult::failure>();
 }
 
 
-BufferPoolClient::BufferPoolClient(const sp<Accessor> &accessor,
-                                   const sp<IObserver> &observer) {
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+                                   const std::shared_ptr<IObserver> &observer) {
     mImpl = std::make_shared<Impl>(accessor, observer);
 }
 
-BufferPoolClient::BufferPoolClient(const sp<IAccessor> &accessor,
-                                   const sp<IObserver> &observer) {
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+                                   const std::shared_ptr<IObserver> &observer) {
     mImpl = std::make_shared<Impl>(accessor, observer);
 }
 
@@ -799,12 +786,12 @@
     return mImpl && mImpl->isLocal();
 }
 
-bool BufferPoolClient::isActive(int64_t *lastTransactionUs, bool clearCache) {
+bool BufferPoolClient::isActive(int64_t *lastTransactionMs, bool clearCache) {
     if (!isValid()) {
-        *lastTransactionUs = 0;
+        *lastTransactionMs = 0;
         return false;
     }
-    return mImpl->isActive(lastTransactionUs, clearCache);
+    return mImpl->isActive(lastTransactionMs, clearCache);
 }
 
 ConnectionId BufferPoolClient::getConnectionId() {
@@ -814,7 +801,7 @@
     return -1;
 }
 
-ResultStatus BufferPoolClient::getAccessor(sp<IAccessor> *accessor) {
+BufferPoolStatus BufferPoolClient::getAccessor(std::shared_ptr<IAccessor> *accessor) {
     if (isValid()) {
         *accessor = mImpl->getAccessor();
         return ResultStatus::OK;
@@ -829,14 +816,14 @@
     }
 }
 
-ResultStatus BufferPoolClient::flush() {
+BufferPoolStatus BufferPoolClient::flush() {
     if (isValid()) {
         return mImpl->flush();
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus BufferPoolClient::allocate(
+BufferPoolStatus BufferPoolClient::allocate(
         const std::vector<uint8_t> &params,
         native_handle_t **handle,
         std::shared_ptr<BufferPoolData> *buffer) {
@@ -846,31 +833,26 @@
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus BufferPoolClient::receive(
-        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
+BufferPoolStatus BufferPoolClient::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
         native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
     if (isValid()) {
-        return mImpl->receive(transactionId, bufferId, timestampUs, handle, buffer);
+        return mImpl->receive(transactionId, bufferId, timestampMs, handle, buffer);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus BufferPoolClient::postSend(
+BufferPoolStatus BufferPoolClient::postSend(
         ConnectionId receiverId,
         const std::shared_ptr<BufferPoolData> &buffer,
         TransactionId *transactionId,
-        int64_t *timestampUs) {
+        int64_t *timestampMs) {
     if (isValid()) {
         bool result = mImpl->postSend(
-                buffer->mId, receiverId, transactionId, timestampUs);
+                buffer->mId, receiverId, transactionId, timestampMs);
         return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.h b/media/bufferpool/aidl/default/BufferPoolClient.h
index e8d9ae6..80fd43e 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.h
+++ b/media/bufferpool/aidl/default/BufferPoolClient.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,29 +14,19 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
+#pragma once
 
 #include <memory>
-#include <android/hardware/media/bufferpool/2.0/IAccessor.h>
-#include <android/hardware/media/bufferpool/2.0/IConnection.h>
-#include <android/hardware/media/bufferpool/2.0/IObserver.h>
-#include <bufferpool/BufferPoolTypes.h>
-#include <cutils/native_handle.h>
-#include "Accessor.h"
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-using ::android::hardware::media::bufferpool::V2_0::IAccessor;
-using ::android::hardware::media::bufferpool::V2_0::IConnection;
-using ::android::hardware::media::bufferpool::V2_0::IObserver;
-using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
-using ::android::sp;
+using aidl::android::hardware::media::bufferpool2::IAccessor;
+using aidl::android::hardware::media::bufferpool2::IObserver;
+
+struct Accessor;
 
 /**
  * A buffer pool client for a buffer pool. For a specific buffer pool, at most
@@ -49,8 +39,8 @@
      * Creates a buffer pool client from a local buffer pool
      * (via ClientManager#create).
      */
-    explicit BufferPoolClient(const sp<Accessor> &accessor,
-                              const sp<IObserver> &observer);
+    explicit BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+                              const std::shared_ptr<IObserver> &observer);
 
     /**
      * Creates a buffer pool client from a remote buffer pool
@@ -58,8 +48,8 @@
      * Note: A buffer pool client created with remote buffer pool cannot
      * allocate a buffer.
      */
-    explicit BufferPoolClient(const sp<IAccessor> &accessor,
-                              const sp<IObserver> &observer);
+    explicit BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+                              const std::shared_ptr<IObserver> &observer);
 
     /** Destructs a buffer pool client. */
     ~BufferPoolClient();
@@ -69,30 +59,30 @@
 
     bool isLocal();
 
-    bool isActive(int64_t *lastTransactionUs, bool clearCache);
+    bool isActive(int64_t *lastTransactionMs, bool clearCache);
 
     ConnectionId getConnectionId();
 
-    ResultStatus getAccessor(sp<IAccessor> *accessor);
+    BufferPoolStatus getAccessor(std::shared_ptr<IAccessor> *accessor);
 
     void receiveInvalidation(uint32_t msgId);
 
-    ResultStatus flush();
+    BufferPoolStatus flush();
 
-    ResultStatus allocate(const std::vector<uint8_t> &params,
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
                           native_handle_t **handle,
                           std::shared_ptr<BufferPoolData> *buffer);
 
-    ResultStatus receive(TransactionId transactionId,
+    BufferPoolStatus receive(TransactionId transactionId,
                          BufferId bufferId,
-                         int64_t timestampUs,
+                         int64_t timestampMs,
                          native_handle_t **handle,
                          std::shared_ptr<BufferPoolData> *buffer);
 
-    ResultStatus postSend(ConnectionId receiver,
+    BufferPoolStatus postSend(ConnectionId receiver,
                           const std::shared_ptr<BufferPoolData> &buffer,
                           TransactionId *transactionId,
-                          int64_t *timestampUs);
+                          int64_t *timestampMs);
 
     class Impl;
     std::shared_ptr<Impl> mImpl;
@@ -101,11 +91,4 @@
     friend struct Observer;
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLCLIENT_H
+}  // namespace aidl::android::hardware::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferStatus.cpp b/media/bufferpool/aidl/default/BufferStatus.cpp
index 6937260..19caa1e 100644
--- a/media/bufferpool/aidl/default/BufferStatus.cpp
+++ b/media/bufferpool/aidl/default/BufferStatus.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,29 +14,17 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "BufferPoolStatus"
+#define LOG_TAG "AidlBufferPoolStatus"
 //#define LOG_NDEBUG 0
 
 #include <thread>
 #include <time.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatus.h>
 #include "BufferStatus.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-int64_t getTimestampNow() {
-    int64_t stamp;
-    struct timespec ts;
-    // TODO: CLOCK_MONOTONIC_COARSE?
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    stamp = ts.tv_nsec / 1000;
-    stamp += (ts.tv_sec * 1000000LL);
-    return stamp;
-}
+using aidl::android::hardware::media::bufferpool2::BufferStatus;
 
 bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId) {
     return curMsgId != prevMsgId && curMsgId - prevMsgId < prevMsgId - curMsgId;
@@ -53,30 +41,26 @@
 static constexpr int kNumElementsInQueue = 1024*16;
 static constexpr int kMinElementsToSyncInQueue = 128;
 
-ResultStatus BufferStatusObserver::open(
-        ConnectionId id, const StatusDescriptor** fmqDescPtr) {
+BufferPoolStatus BufferStatusObserver::open(
+        ConnectionId id, StatusDescriptor* fmqDescPtr) {
     if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
-        // TODO: id collision log?
+        ALOGE("connection id collision %lld", (unsigned long long)id);
         return ResultStatus::CRITICAL_ERROR;
     }
-    std::unique_ptr<BufferStatusQueue> queue =
-            std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
+    auto queue = std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
     if (!queue || queue->isValid() == false) {
-        *fmqDescPtr = nullptr;
         return ResultStatus::NO_MEMORY;
-    } else {
-        *fmqDescPtr = queue->getDesc();
     }
+    *fmqDescPtr = queue->dupeDesc();
     auto result = mBufferStatusQueues.insert(
             std::make_pair(id, std::move(queue)));
     if (!result.second) {
-        *fmqDescPtr = nullptr;
         return ResultStatus::NO_MEMORY;
     }
     return ResultStatus::OK;
 }
 
-ResultStatus BufferStatusObserver::close(ConnectionId id) {
+BufferPoolStatus BufferStatusObserver::close(ConnectionId id) {
     if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
         return ResultStatus::CRITICAL_ERROR;
     }
@@ -90,7 +74,7 @@
         size_t avail = it->second->availableToRead();
         while (avail > 0) {
             if (!it->second->read(&message, 1)) {
-                // Since avaliable # of reads are already confirmed,
+                // Since available # of reads are already confirmed,
                 // this should not happen.
                 // TODO: error handling (spurious client?)
                 ALOGW("FMQ message cannot be read from %lld", (long long)it->first);
@@ -105,8 +89,7 @@
 
 BufferStatusChannel::BufferStatusChannel(
         const StatusDescriptor &fmqDesc) {
-    std::unique_ptr<BufferStatusQueue> queue =
-            std::make_unique<BufferStatusQueue>(fmqDesc);
+    auto queue = std::make_unique<BufferStatusQueue>(fmqDesc);
     if (!queue || queue->isValid() == false) {
         mValid = false;
         return;
@@ -136,11 +119,11 @@
         BufferStatusMessage message;
         for (size_t i = 0 ; i < avail; ++i) {
             BufferId id = pending.front();
-            message.newStatus = BufferStatus::NOT_USED;
+            message.status = BufferStatus::NOT_USED;
             message.bufferId = id;
             message.connectionId = connectionId;
             if (!mBufferStatusQueue->write(&message, 1)) {
-                // Since avaliable # of writes are already confirmed,
+                // Since available # of writes are already confirmed,
                 // this should not happen.
                 // TODO: error handing?
                 ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
@@ -160,11 +143,11 @@
         size_t avail = mBufferStatusQueue->availableToWrite();
         if (avail > 0) {
             BufferStatusMessage message;
-            message.newStatus = BufferStatus::INVALIDATION_ACK;
+            message.status = BufferStatus::INVALIDATION_ACK;
             message.bufferId = invalidateId;
             message.connectionId = connectionId;
             if (!mBufferStatusQueue->write(&message, 1)) {
-                // Since avaliable # of writes are already confirmed,
+                // Since available # of writes are already confirmed,
                 // this should not happen.
                 // TODO: error handing?
                 ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
@@ -186,11 +169,11 @@
             BufferStatusMessage release, message;
             for (size_t i = 0; i < numPending; ++i) {
                 BufferId id = pending.front();
-                release.newStatus = BufferStatus::NOT_USED;
+                release.status = BufferStatus::NOT_USED;
                 release.bufferId = id;
                 release.connectionId = connectionId;
                 if (!mBufferStatusQueue->write(&release, 1)) {
-                    // Since avaliable # of writes are already confirmed,
+                    // Since available # of writes are already confirmed,
                     // this should not happen.
                     // TODO: error handling?
                     ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
@@ -201,13 +184,13 @@
             }
             message.transactionId = transactionId;
             message.bufferId = bufferId;
-            message.newStatus = status;
+            message.status = status;
             message.connectionId = connectionId;
             message.targetConnectionId = targetId;
             // TODO : timesatamp
             message.timestampUs = 0;
             if (!mBufferStatusQueue->write(&message, 1)) {
-                // Since avaliable # of writes are already confirmed,
+                // Since available # of writes are already confirmed,
                 // this should not happen.
                 ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
                 return false;
@@ -276,12 +259,11 @@
     return mValid;
 }
 
-void BufferInvalidationChannel::getDesc(const InvalidationDescriptor **fmqDescPtr) {
+void BufferInvalidationChannel::getDesc(InvalidationDescriptor *fmqDescPtr) {
     if (mValid) {
-        *fmqDescPtr = mBufferInvalidationQueue->getDesc();
-    } else {
-        *fmqDescPtr = nullptr;
+        *fmqDescPtr = mBufferInvalidationQueue->dupeDesc();
     }
+    // TODO: writing invalid descriptor?
 }
 
 void BufferInvalidationChannel::postInvalidation(
@@ -295,10 +277,5 @@
     mBufferInvalidationQueue->write(&message);
 }
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
 
diff --git a/media/bufferpool/aidl/default/BufferStatus.h b/media/bufferpool/aidl/default/BufferStatus.h
index fa65838..3dd92f4 100644
--- a/media/bufferpool/aidl/default/BufferStatus.h
+++ b/media/bufferpool/aidl/default/BufferStatus.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,28 +14,16 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
+#pragma once
 
-#include <android/hardware/media/bufferpool/2.0/types.h>
-#include <bufferpool/BufferPoolTypes.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
+#include <bufferpool2/BufferPoolTypes.h>
+#include <map>
 #include <memory>
 #include <mutex>
 #include <vector>
 #include <list>
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
-
-/** Returns monotonic timestamp in Us since fixed point in time. */
-int64_t getTimestampNow();
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
 bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId);
 
@@ -55,13 +43,13 @@
      * connection(client).
      *
      * @param connectionId  connection Id of the specified client.
-     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
+     * @param fmqDescPtr    ptr of created FMQ's descriptor.
      *
      * @return OK if FMQ is created successfully.
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus open(ConnectionId id, const StatusDescriptor** fmqDescPtr);
+    BufferPoolStatus open(ConnectionId id, StatusDescriptor* _Nonnull fmqDescPtr);
 
     /** Closes a buffer status message FMQ for the specified
      * connection(client).
@@ -71,7 +59,7 @@
      * @return OK if the specified connection is closed successfully.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus close(ConnectionId id);
+    BufferPoolStatus close(ConnectionId id);
 
     /** Retrieves all pending FMQ buffer status messages from clients.
      *
@@ -140,7 +128,7 @@
             std::list<BufferId> &pending, std::list<BufferId> &posted);
 
     /**
-     * Posts a buffer invaliadation messge to the buffer pool.
+     * Posts a buffer invaliadation message to the buffer pool.
      *
      * @param connectionId  connection Id of the client.
      * @param invalidateId  invalidation ack to the buffer pool.
@@ -152,7 +140,7 @@
     void postBufferInvalidateAck(
             ConnectionId connectionId,
             uint32_t invalidateId,
-            bool *invalidated);
+            bool* _Nonnull invalidated);
 };
 
 /**
@@ -179,7 +167,7 @@
      */
     void getInvalidations(std::vector<BufferInvalidationMessage> &messages);
 
-    /** Returns whether the FMQ is connected succesfully. */
+    /** Returns whether the FMQ is connected successfully. */
     bool isValid();
 };
 
@@ -199,16 +187,16 @@
      */
     BufferInvalidationChannel();
 
-    /** Returns whether the FMQ is connected succesfully. */
+    /** Returns whether the FMQ is connected successfully. */
     bool isValid();
 
     /**
      * Retrieves the descriptor of a buffer invalidation FMQ. the descriptor may
      * be passed to the client for buffer invalidation handling.
      *
-     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
+     * @param fmqDescPtr    ptr of created FMQ's descriptor.
      */
-    void getDesc(const InvalidationDescriptor **fmqDescPtr);
+    void getDesc(InvalidationDescriptor* _Nonnull fmqDescPtr);
 
     /** Posts a buffer invalidation for invalidated buffers.
      *
@@ -220,11 +208,4 @@
     void postInvalidation(uint32_t msgId, BufferId fromId, BufferId toId);
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERSTATUS_H
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/ClientManager.cpp b/media/bufferpool/aidl/default/ClientManager.cpp
index 54a20b9..de1db50 100644
--- a/media/bufferpool/aidl/default/ClientManager.cpp
+++ b/media/bufferpool/aidl/default/ClientManager.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -13,122 +13,74 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "BufferPoolManager"
+#define LOG_TAG "AidlBufferPoolMgr"
 //#define LOG_NDEBUG 0
 
-#include <bufferpool/ClientManager.h>
-#include <hidl/HidlTransportSupport.h>
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+#include <bufferpool2/ClientManager.h>
+
 #include <sys/types.h>
-#include <time.h>
+#include <utils/SystemClock.h>
 #include <unistd.h>
 #include <utils/Log.h>
+
+#include <chrono>
+
 #include "BufferPoolClient.h"
 #include "Observer.h"
 #include "Accessor.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-static constexpr int64_t kRegisterTimeoutUs = 500000; // 0.5 sec
-static constexpr int64_t kCleanUpDurationUs = 1000000; // TODO: 1 sec tune
-static constexpr int64_t kClientTimeoutUs = 5000000; // TODO: 5 secs tune
+using namespace std::chrono_literals;
 
-/**
- * The holder of the cookie of remote IClientManager.
- * The cookie is process locally unique for each IClientManager.
- * (The cookie is used to notify death of clients to bufferpool process.)
- */
-class ClientManagerCookieHolder {
-public:
-    /**
-     * Creates a cookie holder for remote IClientManager(s).
-     */
-    ClientManagerCookieHolder();
+using Registration = aidl::android::hardware::media::bufferpool2::IClientManager::Registration;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
 
-    /**
-     * Gets a cookie for a remote IClientManager.
-     *
-     * @param manager   the specified remote IClientManager.
-     * @param added     true when the specified remote IClientManager is added
-     *                  newly, false otherwise.
-     *
-     * @return the process locally unique cookie for the specified IClientManager.
-     */
-    uint64_t getCookie(const sp<IClientManager> &manager, bool *added);
-
-private:
-    uint64_t mSeqId;
-    std::mutex mLock;
-    std::list<std::pair<const wp<IClientManager>, uint64_t>> mManagers;
-};
-
-ClientManagerCookieHolder::ClientManagerCookieHolder() : mSeqId(0){}
-
-uint64_t ClientManagerCookieHolder::getCookie(
-        const sp<IClientManager> &manager,
-        bool *added) {
-    std::lock_guard<std::mutex> lock(mLock);
-    for (auto it = mManagers.begin(); it != mManagers.end();) {
-        const sp<IClientManager> key = it->first.promote();
-        if (key) {
-            if (interfacesEqual(key, manager)) {
-                *added = false;
-                return it->second;
-            }
-            ++it;
-        } else {
-            it = mManagers.erase(it);
-        }
-    }
-    uint64_t id = mSeqId++;
-    *added = true;
-    mManagers.push_back(std::make_pair(manager, id));
-    return id;
-}
+static constexpr int64_t kRegisterTimeoutMs = 500; // 0.5 sec
+static constexpr int64_t kCleanUpDurationMs = 1000; // TODO: 1 sec tune
+static constexpr int64_t kClientTimeoutMs = 5000; // TODO: 5 secs tune
 
 class ClientManager::Impl {
 public:
     Impl();
 
     // BnRegisterSender
-    ResultStatus registerSender(const sp<IAccessor> &accessor,
-                                ConnectionId *pConnectionId);
+    BufferPoolStatus registerSender(const std::shared_ptr<IAccessor> &accessor,
+                                Registration *pRegistration);
 
     // BpRegisterSender
-    ResultStatus registerSender(const sp<IClientManager> &receiver,
+    BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
                                 ConnectionId senderId,
-                                ConnectionId *receiverId);
+                                ConnectionId *receiverId,
+                                bool *isNew);
 
-    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+    BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
                         ConnectionId *pConnectionId);
 
-    ResultStatus close(ConnectionId connectionId);
+    BufferPoolStatus close(ConnectionId connectionId);
 
-    ResultStatus flush(ConnectionId connectionId);
+    BufferPoolStatus flush(ConnectionId connectionId);
 
-    ResultStatus allocate(ConnectionId connectionId,
+    BufferPoolStatus allocate(ConnectionId connectionId,
                           const std::vector<uint8_t> &params,
                           native_handle_t **handle,
                           std::shared_ptr<BufferPoolData> *buffer);
 
-    ResultStatus receive(ConnectionId connectionId,
+    BufferPoolStatus receive(ConnectionId connectionId,
                          TransactionId transactionId,
                          BufferId bufferId,
-                         int64_t timestampUs,
+                         int64_t timestampMs,
                          native_handle_t **handle,
                          std::shared_ptr<BufferPoolData> *buffer);
 
-    ResultStatus postSend(ConnectionId receiverId,
+    BufferPoolStatus postSend(ConnectionId receiverId,
                           const std::shared_ptr<BufferPoolData> &buffer,
                           TransactionId *transactionId,
-                          int64_t *timestampUs);
+                          int64_t *timestampMs);
 
-    ResultStatus getAccessor(ConnectionId connectionId,
-                             sp<IAccessor> *accessor);
+    BufferPoolStatus getAccessor(ConnectionId connectionId,
+                             std::shared_ptr<IAccessor> *accessor);
 
     void cleanUp(bool clearCache = false);
 
@@ -139,13 +91,13 @@
         // This lock is held for brief duration.
         // Blocking operation is not performed while holding the lock.
         std::mutex mMutex;
-        std::list<std::pair<const wp<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
+        std::list<std::pair<const std::weak_ptr<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
                 mClients;
         std::condition_variable mConnectCv;
         bool mConnecting;
-        int64_t mLastCleanUpUs;
+        int64_t mLastCleanUpMs;
 
-        ClientCache() : mConnecting(false), mLastCleanUpUs(getTimestampNow()) {}
+        ClientCache() : mConnecting(false), mLastCleanUpMs(::android::elapsedRealtime()) {}
     } mCache;
 
     // Active clients which can be retrieved via ConnectionId
@@ -157,30 +109,31 @@
                 mClients;
     } mActive;
 
-    sp<Observer> mObserver;
-
-    ClientManagerCookieHolder mRemoteClientCookies;
+    std::shared_ptr<Observer> mObserver;
 };
 
 ClientManager::Impl::Impl()
-    : mObserver(new Observer()) {}
+    : mObserver(::ndk::SharedRefBase::make<Observer>()) {}
 
-ResultStatus ClientManager::Impl::registerSender(
-        const sp<IAccessor> &accessor, ConnectionId *pConnectionId) {
+BufferPoolStatus ClientManager::Impl::registerSender(
+        const std::shared_ptr<IAccessor> &accessor, Registration *pRegistration) {
     cleanUp();
-    int64_t timeoutUs = getTimestampNow() + kRegisterTimeoutUs;
+    int64_t timeoutMs = ::android::elapsedRealtime() + kRegisterTimeoutMs;
     do {
         std::unique_lock<std::mutex> lock(mCache.mMutex);
         for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
-            sp<IAccessor> sAccessor = it->first.promote();
-            if (sAccessor && interfacesEqual(sAccessor, accessor)) {
+            std::shared_ptr<IAccessor> sAccessor = it->first.lock();
+            if (sAccessor && sAccessor.get() == accessor.get()) {
                 const std::shared_ptr<BufferPoolClient> client = it->second.lock();
                 if (client) {
                     std::lock_guard<std::mutex> lock(mActive.mMutex);
-                    *pConnectionId = client->getConnectionId();
-                    if (mActive.mClients.find(*pConnectionId) != mActive.mClients.end()) {
-                        ALOGV("register existing connection %lld", (long long)*pConnectionId);
-                        return ResultStatus::ALREADY_EXISTS;
+                    pRegistration->connectionId = client->getConnectionId();
+                    if (mActive.mClients.find(pRegistration->connectionId)
+                            != mActive.mClients.end()) {
+                        ALOGV("register existing connection %lld",
+                              (long long)pRegistration->connectionId);
+                        pRegistration->isNew = false;
+                        return ResultStatus::OK;
                     }
                 }
                 mCache.mClients.erase(it);
@@ -190,7 +143,7 @@
         if (!mCache.mConnecting) {
             mCache.mConnecting = true;
             lock.unlock();
-            ResultStatus result = ResultStatus::OK;
+            BufferPoolStatus result = ResultStatus::OK;
             const std::shared_ptr<BufferPoolClient> client =
                     std::make_shared<BufferPoolClient>(accessor, mObserver);
             lock.lock();
@@ -209,26 +162,27 @@
                     std::lock_guard<std::mutex> lock(mActive.mMutex);
                     mActive.mClients.insert(std::make_pair(conId, client));
                 }
-                *pConnectionId = conId;
-                ALOGV("register new connection %lld", (long long)*pConnectionId);
+                pRegistration->connectionId = conId;
+                pRegistration->isNew = true;
+                ALOGV("register new connection %lld", (long long)conId);
             }
             mCache.mConnecting = false;
             lock.unlock();
             mCache.mConnectCv.notify_all();
             return result;
         }
-        mCache.mConnectCv.wait_for(
-                lock, std::chrono::microseconds(kRegisterTimeoutUs));
-    } while (getTimestampNow() < timeoutUs);
+        mCache.mConnectCv.wait_for(lock, kRegisterTimeoutMs*1ms);
+    } while (::android::elapsedRealtime() < timeoutMs);
     // TODO: return timeout error
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::Impl::registerSender(
-        const sp<IClientManager> &receiver,
+BufferPoolStatus ClientManager::Impl::registerSender(
+        const std::shared_ptr<IClientManager> &receiver,
         ConnectionId senderId,
-        ConnectionId *receiverId) {
-    sp<IAccessor> accessor;
+        ConnectionId *receiverId,
+        bool *isNew) {
+    std::shared_ptr<IAccessor> accessor;
     bool local = false;
     {
         std::lock_guard<std::mutex> lock(mActive.mMutex);
@@ -239,38 +193,32 @@
         it->second->getAccessor(&accessor);
         local = it->second->isLocal();
     }
-    ResultStatus rs = ResultStatus::CRITICAL_ERROR;
     if (accessor) {
-       Return<void> transResult = receiver->registerSender(
-                accessor,
-                [&rs, receiverId](
-                        ResultStatus status,
-                        int64_t connectionId) {
-                    rs = status;
-                    *receiverId = connectionId;
-                });
-        if (!transResult.isOk()) {
+        Registration registration;
+        ::ndk::ScopedAStatus status = receiver->registerSender(accessor, &registration);
+        if (!status.isOk()) {
             return ResultStatus::CRITICAL_ERROR;
-        } else if (local && rs == ResultStatus::OK) {
-            sp<ConnectionDeathRecipient> recipient = Accessor::getConnectionDeathRecipient();
+        } else if (local) {
+            std::shared_ptr<ConnectionDeathRecipient> recipient =
+                    Accessor::getConnectionDeathRecipient();
             if (recipient)  {
                 ALOGV("client death recipient registered %lld", (long long)*receiverId);
-                bool added;
-                uint64_t cookie = mRemoteClientCookies.getCookie(receiver, &added);
-                recipient->addCookieToConnection(cookie, *receiverId);
-                if (added) {
-                    Return<bool> transResult = receiver->linkToDeath(recipient, cookie);
-                }
+                recipient->addCookieToConnection(receiver->asBinder().get(), *receiverId);
+                AIBinder_linkToDeath(receiver->asBinder().get(), recipient->getRecipient(),
+                                     receiver->asBinder().get());
             }
         }
+        *receiverId = registration.connectionId;
+        *isNew = registration.isNew;
+        return ResultStatus::OK;
     }
-    return rs;
+    return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::Impl::create(
+BufferPoolStatus ClientManager::Impl::create(
         const std::shared_ptr<BufferPoolAllocator> &allocator,
         ConnectionId *pConnectionId) {
-    const sp<Accessor> accessor = new Accessor(allocator);
+    std::shared_ptr<Accessor> accessor = ::ndk::SharedRefBase::make<Accessor>(allocator);
     if (!accessor || !accessor->isValid()) {
         return ResultStatus::CRITICAL_ERROR;
     }
@@ -300,19 +248,19 @@
     return ResultStatus::OK;
 }
 
-ResultStatus ClientManager::Impl::close(ConnectionId connectionId) {
+BufferPoolStatus ClientManager::Impl::close(ConnectionId connectionId) {
     std::unique_lock<std::mutex> lock1(mCache.mMutex);
     std::unique_lock<std::mutex> lock2(mActive.mMutex);
     auto it = mActive.mClients.find(connectionId);
     if (it != mActive.mClients.end()) {
-        sp<IAccessor> accessor;
+        std::shared_ptr<IAccessor> accessor;
         it->second->getAccessor(&accessor);
         std::shared_ptr<BufferPoolClient> closing = it->second;
         mActive.mClients.erase(connectionId);
         for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
             // clean up dead client caches
-            sp<IAccessor> cAccessor = cit->first.promote();
-            if (!cAccessor || (accessor && interfacesEqual(cAccessor, accessor))) {
+            std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
+            if (!cAccessor || (accessor && cAccessor.get() ==  accessor.get())) {
                 cit = mCache.mClients.erase(cit);
             } else {
                 cit++;
@@ -326,7 +274,7 @@
     return ResultStatus::NOT_FOUND;
 }
 
-ResultStatus ClientManager::Impl::flush(ConnectionId connectionId) {
+BufferPoolStatus ClientManager::Impl::flush(ConnectionId connectionId) {
     std::shared_ptr<BufferPoolClient> client;
     {
         std::lock_guard<std::mutex> lock(mActive.mMutex);
@@ -339,7 +287,7 @@
     return client->flush();
 }
 
-ResultStatus ClientManager::Impl::allocate(
+BufferPoolStatus ClientManager::Impl::allocate(
         ConnectionId connectionId, const std::vector<uint8_t> &params,
         native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
     std::shared_ptr<BufferPoolClient> client;
@@ -353,7 +301,7 @@
     }
 #ifdef BUFFERPOOL_CLONE_HANDLES
     native_handle_t *origHandle;
-    ResultStatus res = client->allocate(params, &origHandle, buffer);
+    BufferPoolStatus res = client->allocate(params, &origHandle, buffer);
     if (res != ResultStatus::OK) {
         return res;
     }
@@ -368,9 +316,9 @@
 #endif
 }
 
-ResultStatus ClientManager::Impl::receive(
+BufferPoolStatus ClientManager::Impl::receive(
         ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, int64_t timestampUs,
+        BufferId bufferId, int64_t timestampMs,
         native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
     std::shared_ptr<BufferPoolClient> client;
     {
@@ -383,8 +331,8 @@
     }
 #ifdef BUFFERPOOL_CLONE_HANDLES
     native_handle_t *origHandle;
-    ResultStatus res = client->receive(
-            transactionId, bufferId, timestampUs, &origHandle, buffer);
+    BufferPoolStatus res = client->receive(
+            transactionId, bufferId, timestampMs, &origHandle, buffer);
     if (res != ResultStatus::OK) {
         return res;
     }
@@ -395,13 +343,13 @@
     }
     return ResultStatus::OK;
 #else
-    return client->receive(transactionId, bufferId, timestampUs, handle, buffer);
+    return client->receive(transactionId, bufferId, timestampMs, handle, buffer);
 #endif
 }
 
-ResultStatus ClientManager::Impl::postSend(
+BufferPoolStatus ClientManager::Impl::postSend(
         ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
-        TransactionId *transactionId, int64_t *timestampUs) {
+        TransactionId *transactionId, int64_t *timestampMs) {
     ConnectionId connectionId = buffer->mConnectionId;
     std::shared_ptr<BufferPoolClient> client;
     {
@@ -412,11 +360,11 @@
         }
         client = it->second;
     }
-    return client->postSend(receiverId, buffer, transactionId, timestampUs);
+    return client->postSend(receiverId, buffer, transactionId, timestampMs);
 }
 
-ResultStatus ClientManager::Impl::getAccessor(
-        ConnectionId connectionId, sp<IAccessor> *accessor) {
+BufferPoolStatus ClientManager::Impl::getAccessor(
+        ConnectionId connectionId, std::shared_ptr<IAccessor> *accessor) {
     std::shared_ptr<BufferPoolClient> client;
     {
         std::lock_guard<std::mutex> lock(mActive.mMutex);
@@ -430,16 +378,16 @@
 }
 
 void ClientManager::Impl::cleanUp(bool clearCache) {
-    int64_t now = getTimestampNow();
-    int64_t lastTransactionUs;
+    int64_t now = ::android::elapsedRealtime();
+    int64_t lastTransactionMs;
     std::lock_guard<std::mutex> lock1(mCache.mMutex);
-    if (clearCache || mCache.mLastCleanUpUs + kCleanUpDurationUs < now) {
+    if (clearCache || mCache.mLastCleanUpMs + kCleanUpDurationMs < now) {
         std::lock_guard<std::mutex> lock2(mActive.mMutex);
         int cleaned = 0;
         for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
-            if (!it->second->isActive(&lastTransactionUs, clearCache)) {
-                if (lastTransactionUs + kClientTimeoutUs < now) {
-                    sp<IAccessor> accessor;
+            if (!it->second->isActive(&lastTransactionMs, clearCache)) {
+                if (lastTransactionMs + kClientTimeoutMs < now) {
+                  std::shared_ptr<IAccessor> accessor;
                     it->second->getAccessor(&accessor);
                     it = mActive.mClients.erase(it);
                     ++cleaned;
@@ -450,7 +398,7 @@
         }
         for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
             // clean up dead client caches
-            sp<IAccessor> cAccessor = cit->first.promote();
+          std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
             if (!cAccessor) {
                 cit = mCache.mClients.erase(cit);
             } else {
@@ -458,30 +406,32 @@
             }
         }
         ALOGV("# of cleaned connections: %d", cleaned);
-        mCache.mLastCleanUpUs = now;
+        mCache.mLastCleanUpMs = now;
     }
 }
 
-// Methods from ::android::hardware::media::bufferpool::V2_0::IClientManager follow.
-Return<void> ClientManager::registerSender(const sp<::android::hardware::media::bufferpool::V2_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) {
+::ndk::ScopedAStatus ClientManager::registerSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
     if (mImpl) {
-        ConnectionId connectionId = -1;
-        ResultStatus status = mImpl->registerSender(bufferPool, &connectionId);
-        _hidl_cb(status, connectionId);
-    } else {
-        _hidl_cb(ResultStatus::CRITICAL_ERROR, -1);
+        status = mImpl->registerSender(in_bufferPool, _aidl_return);
     }
-    return Void();
+    if (status != ResultStatus::OK) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+    }
+    return ::ndk::ScopedAStatus::ok();
 }
 
 // Methods for local use.
-sp<ClientManager> ClientManager::sInstance;
+std::shared_ptr<ClientManager> ClientManager::sInstance;
 std::mutex ClientManager::sInstanceLock;
 
-sp<ClientManager> ClientManager::getInstance() {
+std::shared_ptr<ClientManager> ClientManager::getInstance() {
     std::lock_guard<std::mutex> lock(sInstanceLock);
     if (!sInstance) {
-        sInstance = new ClientManager();
+        sInstance = ::ndk::SharedRefBase::make<ClientManager>();
+        // TODO: configure thread count for threadpool properly
+        // after b/261652496 is resolved.
     }
     Accessor::createInvalidator();
     Accessor::createEvictor();
@@ -493,7 +443,7 @@
 ClientManager::~ClientManager() {
 }
 
-ResultStatus ClientManager::create(
+BufferPoolStatus ClientManager::create(
         const std::shared_ptr<BufferPoolAllocator> &allocator,
         ConnectionId *pConnectionId) {
     if (mImpl) {
@@ -502,31 +452,32 @@
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::registerSender(
-        const sp<IClientManager> &receiver,
+BufferPoolStatus ClientManager::registerSender(
+        const std::shared_ptr<IClientManager> &receiver,
         ConnectionId senderId,
-        ConnectionId *receiverId) {
+        ConnectionId *receiverId,
+        bool *isNew) {
     if (mImpl) {
-        return mImpl->registerSender(receiver, senderId, receiverId);
+        return mImpl->registerSender(receiver, senderId, receiverId, isNew);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::close(ConnectionId connectionId) {
+BufferPoolStatus ClientManager::close(ConnectionId connectionId) {
     if (mImpl) {
         return mImpl->close(connectionId);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::flush(ConnectionId connectionId) {
+BufferPoolStatus ClientManager::flush(ConnectionId connectionId) {
     if (mImpl) {
         return mImpl->flush(connectionId);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::allocate(
+BufferPoolStatus ClientManager::allocate(
         ConnectionId connectionId, const std::vector<uint8_t> &params,
         native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
     if (mImpl) {
@@ -535,22 +486,22 @@
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::receive(
+BufferPoolStatus ClientManager::receive(
         ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, int64_t timestampUs,
+        BufferId bufferId, int64_t timestampMs,
         native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
     if (mImpl) {
         return mImpl->receive(connectionId, transactionId, bufferId,
-                              timestampUs, handle, buffer);
+                              timestampMs, handle, buffer);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus ClientManager::postSend(
+BufferPoolStatus ClientManager::postSend(
         ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
-        TransactionId *transactionId, int64_t* timestampUs) {
+        TransactionId *transactionId, int64_t* timestampMs) {
     if (mImpl && buffer) {
-        return mImpl->postSend(receiverId, buffer, transactionId, timestampUs);
+        return mImpl->postSend(receiverId, buffer, transactionId, timestampMs);
     }
     return ResultStatus::CRITICAL_ERROR;
 }
@@ -561,9 +512,4 @@
     }
 }
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.cpp b/media/bufferpool/aidl/default/Connection.cpp
index 57d0c7e..53d350d 100644
--- a/media/bufferpool/aidl/default/Connection.cpp
+++ b/media/bufferpool/aidl/default/Connection.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -13,42 +13,63 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "AidlBufferPoolCon"
+//#define LOG_NDEBUG 0
+
+#include <aidlcommonsupport/NativeHandle.h>
 
 #include "Connection.h"
+#include "Accessor.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-// Methods from ::android::hardware::media::bufferpool::V2_0::IConnection follow.
-Return<void> Connection::fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) {
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using Buffer = aidl::android::hardware::media::bufferpool2::Buffer;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+::ndk::ScopedAStatus Connection::fetch(const std::vector<FetchInfo>& in_fetchInfos,
+                           std::vector<FetchResult>* _aidl_return) {
+    int success = 0;
+    int failure = 0;
     if (mInitialized && mAccessor) {
-        if (bufferId != SYNC_BUFFERID) {
-            const native_handle_t *handle = nullptr;
-            status = mAccessor->fetch(
-                    mConnectionId, transactionId, bufferId, &handle);
-            if (status == ResultStatus::OK) {
-                Buffer buffer = {};
-                buffer.id = bufferId;
-                buffer.buffer = handle;
-                _hidl_cb(status, buffer);
-                return Void();
+        for (auto it = in_fetchInfos.begin(); it != in_fetchInfos.end(); ++it) {
+            if (fetch(it->transactionId, it->bufferId, _aidl_return)) {
+                success++;
+            } else {
+                failure++;
             }
-        } else {
-            mAccessor->cleanUp(false);
         }
+        if (failure > 0) {
+            ALOGD("total fetch %d, failure %d", success + failure, failure);
+        }
+        return ::ndk::ScopedAStatus::ok();
     }
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::CRITICAL_ERROR);
+}
 
-    Buffer buffer = {};
-    buffer.id = 0;
-    buffer.buffer = nullptr;
+::ndk::ScopedAStatus Connection::sync() {
+    if (mInitialized && mAccessor) {
+        mAccessor->cleanUp(false);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
 
-    _hidl_cb(status, buffer);
-    return Void();
+
+bool Connection::fetch(TransactionId transactionId, BufferId bufferId,
+                       std::vector<FetchResult> *result) {
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    const native_handle_t *handle = nullptr;
+    status = mAccessor->fetch(
+            mConnectionId, transactionId, bufferId, &handle);
+    if (status == ResultStatus::OK) {
+        result->emplace_back(FetchResult::make<FetchResult::buffer>());
+        result->back().get<FetchResult::buffer>().id = bufferId;
+        result->back().get<FetchResult::buffer>().buffer = ::android::dupToAidl(handle);
+        return true;
+    }
+    result->emplace_back(FetchResult::make<FetchResult::failure>(status));
+    return false;
 }
 
 Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
@@ -60,7 +81,7 @@
 }
 
 void Connection::initialize(
-        const sp<Accessor>& accessor, ConnectionId connectionId) {
+        const std::shared_ptr<Accessor>& accessor, ConnectionId connectionId) {
     if (!mInitialized) {
         mAccessor = accessor;
         mConnectionId = connectionId;
@@ -68,14 +89,14 @@
     }
 }
 
-ResultStatus Connection::flush() {
+BufferPoolStatus Connection::flush() {
     if (mInitialized && mAccessor) {
         return mAccessor->flush();
     }
     return ResultStatus::CRITICAL_ERROR;
 }
 
-ResultStatus Connection::allocate(
+BufferPoolStatus Connection::allocate(
         const std::vector<uint8_t> &params, BufferId *bufferId,
         const native_handle_t **handle) {
     if (mInitialized && mAccessor) {
@@ -90,15 +111,4 @@
     }
 }
 
-// Methods from ::android::hidl::base::V1_0::IBase follow.
-
-//IConnection* HIDL_FETCH_IConnection(const char* /* name */) {
-//    return new Connection();
-//}
-
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.h b/media/bufferpool/aidl/default/Connection.h
index 8507749..d8298af 100644
--- a/media/bufferpool/aidl/default/Connection.h
+++ b/media/bufferpool/aidl/default/Connection.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,39 +14,28 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
+#pragma once
 
-#include <android/hardware/media/bufferpool/2.0/IConnection.h>
-#include <bufferpool/BufferPoolTypes.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include "Accessor.h"
+#include <memory>
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+#include <aidl/android/hardware/media/bufferpool2/BnConnection.h>
+#include <bufferpool2/BufferPoolTypes.h>
 
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::media::bufferpool::V2_0::implementation::Accessor;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-struct Connection : public IConnection {
-    // Methods from ::android::hardware::media::bufferpool::V2_0::IConnection follow.
-    Return<void> fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) override;
+struct Accessor;
+
+struct Connection : public BnConnection {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+    ::ndk::ScopedAStatus fetch(const std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo>& in_fetchInfos, std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>* _aidl_return) override;
+
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+    ::ndk::ScopedAStatus sync() override;
 
     /**
      * Invalidates all buffers which are active and/or are ready to be recycled.
      */
-    ResultStatus flush();
+    BufferPoolStatus flush();
 
     /**
      * Allocates a buffer using the specified parameters. Recycles a buffer if
@@ -61,7 +50,7 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus allocate(const std::vector<uint8_t> &params,
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
                           BufferId *bufferId, const native_handle_t **handle);
 
     /**
@@ -86,7 +75,7 @@
      * @param accessor      the specified buffer pool.
      * @param connectionId  Id.
      */
-    void initialize(const sp<Accessor> &accessor, ConnectionId connectionId);
+    void initialize(const std::shared_ptr<Accessor> &accessor, ConnectionId connectionId);
 
     enum : uint32_t {
         SYNC_BUFFERID = UINT32_MAX,
@@ -94,15 +83,14 @@
 
 private:
     bool mInitialized;
-    sp<Accessor> mAccessor;
+    std::shared_ptr<Accessor> mAccessor;
     ConnectionId mConnectionId;
+
+    bool fetch(
+        uint64_t transactionId,
+        uint32_t bufferId,
+        std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>
+                *result);
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CONNECTION_H
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/DataHelper.h b/media/bufferpool/aidl/default/DataHelper.h
new file mode 100644
index 0000000..a90b3c7
--- /dev/null
+++ b/media/bufferpool/aidl/default/DataHelper.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+#include <map>
+#include <set>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter == mapOfSet->end()) {
+        std::set<U> valueSet{value};
+        mapOfSet->insert(std::make_pair(key, valueSet));
+        return true;
+    } else if (iter->second.find(value)  == iter->second.end()) {
+        iter->second.insert(value);
+        return true;
+    }
+    return false;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    bool ret = false;
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        if (iter->second.erase(value) > 0) {
+            ret = true;
+        }
+        if (iter->second.size() == 0) {
+            mapOfSet->erase(iter);
+        }
+    }
+    return ret;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        auto setIter = iter->second.find(value);
+        return setIter != iter->second.end();
+    }
+    return false;
+}
+
+// Buffer data structure for internal BufferPool use.(storage/fetching)
+struct InternalBuffer {
+    BufferId mId;
+    size_t mOwnerCount;
+    size_t mTransactionCount;
+    const std::shared_ptr<BufferPoolAllocation> mAllocation;
+    const size_t mAllocSize;
+    const std::vector<uint8_t> mConfig;
+    bool mInvalidated;
+
+    InternalBuffer(
+            BufferId id,
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &allocConfig)
+            : mId(id), mOwnerCount(0), mTransactionCount(0),
+            mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig),
+            mInvalidated(false) {}
+
+    const native_handle_t *handle() {
+        return mAllocation->handle();
+    }
+
+    void invalidate() {
+        mInvalidated = true;
+    }
+};
+
+// Buffer transacion status/message data structure for internal BufferPool use.
+struct TransactionStatus {
+    TransactionId mId;
+    BufferId mBufferId;
+    ConnectionId mSender;
+    ConnectionId mReceiver;
+    BufferStatus mStatus;
+    int64_t mTimestampMs;
+    bool mSenderValidated;
+
+    TransactionStatus(const BufferStatusMessage &message, int64_t timestampMs) {
+        mId = message.transactionId;
+        mBufferId = message.bufferId;
+        mStatus = message.status;
+        mTimestampMs = timestampMs;
+        if (mStatus == BufferStatus::TRANSFER_TO) {
+            mSender = message.connectionId;
+            mReceiver = message.targetConnectionId;
+            mSenderValidated = true;
+        } else {
+            mSender = -1LL;
+            mReceiver = message.connectionId;
+            mSenderValidated = false;
+        }
+    }
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.cpp b/media/bufferpool/aidl/default/Observer.cpp
index 5b23160..a22e825 100644
--- a/media/bufferpool/aidl/default/Observer.cpp
+++ b/media/bufferpool/aidl/default/Observer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -15,13 +15,9 @@
  */
 
 #include "Observer.h"
+#include "BufferPoolClient.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
 Observer::Observer() {
 }
@@ -29,20 +25,19 @@
 Observer::~Observer() {
 }
 
-// Methods from ::android::hardware::media::bufferpool::V2_0::IObserver follow.
-Return<void> Observer::onMessage(int64_t connectionId, uint32_t msgId) {
+::ndk::ScopedAStatus Observer::onMessage(int64_t in_connectionId, int32_t in_msgId) {
     std::unique_lock<std::mutex> lock(mLock);
-    auto it = mClients.find(connectionId);
+    auto it = mClients.find(in_connectionId);
     if (it != mClients.end()) {
         const std::shared_ptr<BufferPoolClient> client = it->second.lock();
         if (!client) {
             mClients.erase(it);
         } else {
             lock.unlock();
-            client->receiveInvalidation(msgId);
+            client->receiveInvalidation(in_msgId);
         }
     }
-    return Void();
+    return ::ndk::ScopedAStatus::ok();
 }
 
 void Observer::addClient(ConnectionId connectionId,
@@ -65,9 +60,4 @@
 }
 
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.h b/media/bufferpool/aidl/default/Observer.h
index 42bd7c1..febb21b 100644
--- a/media/bufferpool/aidl/default/Observer.h
+++ b/media/bufferpool/aidl/default/Observer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,32 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
+#pragma once
 
-#include <android/hardware/media/bufferpool/2.0/IObserver.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include "BufferPoolClient.h"
+#include <map>
+#include <memory>
+#include <mutex>
+#include <aidl/android/hardware/media/bufferpool2/BnObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
+class BufferPoolClient;
 
-struct Observer : public IObserver {
-    // Methods from ::android::hardware::media::bufferpool::V2_0::IObserver follow.
-    Return<void> onMessage(int64_t connectionId, uint32_t msgId) override;
+struct Observer : public BnObserver {
+    ::ndk::ScopedAStatus onMessage(int64_t in_connectionId, int32_t in_msgId) override;
 
     ~Observer();
 
@@ -51,17 +39,11 @@
 private:
     Observer();
 
-    friend struct ClientManager;
+    friend class ::ndk::SharedRefBase;
 
     std::mutex mLock;
     std::map<ConnectionId, const std::weak_ptr<BufferPoolClient>> mClients;
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
 
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_OBSERVER_H
diff --git a/media/bufferpool/aidl/default/include/bufferpool/BufferPoolTypes.h b/media/bufferpool/aidl/default/include/bufferpool/BufferPoolTypes.h
deleted file mode 100644
index 7c906cb..0000000
--- a/media/bufferpool/aidl/default/include/bufferpool/BufferPoolTypes.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2018 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_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
-
-#include <android/hardware/media/bufferpool/2.0/types.h>
-#include <cutils/native_handle.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-
-struct BufferPoolData {
-    // For local use, to specify a bufferpool (client connection) for buffers.
-    // Return value from connect#IAccessor(android.hardware.media.bufferpool@2.0).
-    int64_t mConnectionId;
-    // BufferId
-    uint32_t mId;
-
-    BufferPoolData() : mConnectionId(0), mId(0) {}
-
-    BufferPoolData(
-            int64_t connectionId, uint32_t id)
-            : mConnectionId(connectionId), mId(id) {}
-
-    ~BufferPoolData() {}
-};
-
-namespace V2_0 {
-namespace implementation {
-
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::kUnsynchronizedWrite;
-
-typedef uint32_t BufferId;
-typedef uint64_t TransactionId;
-typedef int64_t ConnectionId;
-
-enum : ConnectionId {
-    INVALID_CONNECTIONID = 0,
-};
-
-typedef android::hardware::MessageQueue<BufferStatusMessage, kSynchronizedReadWrite> BufferStatusQueue;
-typedef BufferStatusQueue::Descriptor StatusDescriptor;
-
-typedef android::hardware::MessageQueue<BufferInvalidationMessage, kUnsynchronizedWrite>
-        BufferInvalidationQueue;
-typedef BufferInvalidationQueue::Descriptor InvalidationDescriptor;
-
-/**
- * Allocation wrapper class for buffer pool.
- */
-struct BufferPoolAllocation {
-    const native_handle_t *mHandle;
-
-    const native_handle_t *handle() {
-        return mHandle;
-    }
-
-    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
-
-    ~BufferPoolAllocation() {};
-};
-
-/**
- * Allocator wrapper class for buffer pool.
- */
-class BufferPoolAllocator {
-public:
-
-    /**
-     * Allocate an allocation(buffer) for buffer pool.
-     *
-     * @param params    allocation parameters
-     * @param alloc     created allocation
-     * @param allocSize size of created allocation
-     *
-     * @return OK when an allocation is created successfully.
-     */
-    virtual ResultStatus allocate(
-            const std::vector<uint8_t> &params,
-            std::shared_ptr<BufferPoolAllocation> *alloc,
-            size_t *allocSize) = 0;
-
-    /**
-     * Returns whether allocation parameters of an old allocation are
-     * compatible with new allocation parameters.
-     */
-    virtual bool compatible(const std::vector<uint8_t> &newParams,
-                            const std::vector<uint8_t> &oldParams) = 0;
-
-protected:
-    BufferPoolAllocator() = default;
-
-    virtual ~BufferPoolAllocator() = default;
-};
-
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_BUFFERPOOLTYPES_H
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
new file mode 100644
index 0000000..b833362
--- /dev/null
+++ b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <cutils/native_handle.h>
+#include <fmq/AidlMessageQueue.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+
+namespace aidl::android::hardware::media::bufferpool2 {
+
+struct BufferPoolData {
+    // For local use, to specify a bufferpool (client connection) for buffers.
+    // Retrieved from returned info of IAccessor#connect(android.hardware.media.bufferpool@2.0).
+    int64_t mConnectionId;
+    // BufferId
+    uint32_t mId;
+
+    BufferPoolData() : mConnectionId(0), mId(0) {}
+
+    BufferPoolData(
+            int64_t connectionId, uint32_t id)
+            : mConnectionId(connectionId), mId(id) {}
+
+    ~BufferPoolData() {}
+};
+
+namespace implementation {
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+
+using aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+using aidl::android::hardware::media::bufferpool2::BufferInvalidationMessage;
+
+typedef uint32_t BufferId;
+typedef uint64_t TransactionId;
+typedef int64_t ConnectionId;
+typedef int32_t BufferPoolStatus;
+
+// AIDL hal description language does not support unsigned.
+int32_t static inline ToAidl(BufferId id) {return static_cast<int32_t>(id);}
+int64_t static inline ToAidl(TransactionId id) {return static_cast<int64_t>(id);}
+
+BufferId static inline FromAidl(int32_t id) {return static_cast<BufferId>(id);}
+TransactionId static inline FromAidl(int64_t id) {return static_cast<TransactionId>(id);}
+
+enum : ConnectionId {
+    INVALID_CONNECTIONID = 0,
+};
+
+typedef ::android::AidlMessageQueue<BufferStatusMessage, SynchronizedReadWrite> BufferStatusQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferStatusMessage, SynchronizedReadWrite>
+        StatusDescriptor;
+
+typedef ::android::AidlMessageQueue<BufferInvalidationMessage, UnsynchronizedWrite>
+        BufferInvalidationQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferInvalidationMessage, UnsynchronizedWrite>
+        InvalidationDescriptor;
+
+/**
+ * Allocation wrapper class for buffer pool.
+ */
+struct BufferPoolAllocation {
+    const native_handle_t *mHandle;
+
+    const native_handle_t *handle() {
+        return mHandle;
+    }
+
+    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
+
+    ~BufferPoolAllocation() {};
+};
+
+/**
+ * Allocator wrapper class for buffer pool.
+ */
+class BufferPoolAllocator {
+public:
+
+    /**
+     * Allocate an allocation(buffer) for buffer pool.
+     *
+     * @param params    allocation parameters
+     * @param alloc     created allocation
+     * @param allocSize size of created allocation
+     *
+     * @return OK when an allocation is created successfully.
+     */
+    virtual BufferPoolStatus allocate(
+            const std::vector<uint8_t> &params,
+            std::shared_ptr<BufferPoolAllocation> *alloc,
+            size_t *allocSize) = 0;
+
+    /**
+     * Returns whether allocation parameters of an old allocation are
+     * compatible with new allocation parameters.
+     */
+    virtual bool compatible(const std::vector<uint8_t> &newParams,
+                            const std::vector<uint8_t> &oldParams) = 0;
+
+protected:
+    BufferPoolAllocator() = default;
+
+    virtual ~BufferPoolAllocator() = default;
+};
+
+}  // namespace implementation
+}  // namespace aidl::android::hareware::media::bufferpool2
+
diff --git a/media/bufferpool/aidl/default/include/bufferpool/ClientManager.h b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
similarity index 71%
rename from media/bufferpool/aidl/default/include/bufferpool/ClientManager.h
rename to media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
index 24b61f4..bff75ba 100644
--- a/media/bufferpool/aidl/default/include/bufferpool/ClientManager.h
+++ b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,38 +14,28 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
+#pragma once
 
-#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/BnClientManager.h>
 #include <memory>
 #include "BufferPoolTypes.h"
 
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V2_0 {
-namespace implementation {
+namespace aidl::android::hardware::media::bufferpool2::implementation {
 
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::media::bufferpool::V2_0::IAccessor;
-using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
+using aidl::android::hardware::media::bufferpool2::BnClientManager;
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::IAccessor;
 
-struct ClientManager : public IClientManager {
-    // Methods from ::android::hardware::media::bufferpool::V2_0::IClientManager follow.
-    Return<void> registerSender(const sp<::android::hardware::media::bufferpool::V2_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) override;
+struct ClientManager : public BnClientManager {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IClientManager follow.
+    ::ndk::ScopedAStatus registerSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool,
+        ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
+        override;
 
     /** Gets an instance. */
-    static sp<ClientManager> getInstance();
+    static std::shared_ptr<ClientManager> getInstance();
 
     /**
      * Creates a local connection with a newly created buffer pool.
@@ -56,10 +46,10 @@
      *
      * @return OK when a buffer pool and a local connection is successfully
      *         created.
-     *         NO_MEMORY when there is no memory.
+     *         ResultStatus::NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+    BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
                         ConnectionId *pConnectionId);
 
     /**
@@ -69,16 +59,17 @@
      * @param senderId      A local connection which will send buffers to.
      * @param receiverId    Id of the created receiving connection on the receiver
      *                      process.
+     * @param isNew         @true when the receiving connection is newly created.
      *
      * @return OK when the receiving connection is successfully created on the
      *         receiver process.
      *         NOT_FOUND when the sender connection was not found.
-     *         ALREADY_EXISTS the receiving connection is already made.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus registerSender(const sp<IClientManager> &receiver,
+    BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
                                 ConnectionId senderId,
-                                ConnectionId *receiverId);
+                                ConnectionId *receiverId,
+                                bool *isNew);
 
     /**
      * Closes the specified connection.
@@ -89,7 +80,7 @@
      *         NOT_FOUND when the specified connection was not found.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus close(ConnectionId connectionId);
+    BufferPoolStatus close(ConnectionId connectionId);
 
     /**
      * Evicts cached allocations. If it's local connection, release the
@@ -101,7 +92,7 @@
      *         NOT_FOUND when the specified connection was not found.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus flush(ConnectionId connectionId);
+    BufferPoolStatus flush(ConnectionId connectionId);
 
     /**
      * Allocates a buffer from the specified connection. The output parameter
@@ -119,7 +110,7 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus allocate(ConnectionId connectionId,
+    BufferPoolStatus allocate(ConnectionId connectionId,
                           const std::vector<uint8_t> &params,
                           native_handle_t **handle,
                           std::shared_ptr<BufferPoolData> *buffer);
@@ -132,7 +123,7 @@
      * @param connectionId  The id of the receiving connection.
      * @param transactionId The id for the transaction.
      * @param bufferId      The id for the buffer.
-     * @param timestampUs   The timestamp of the buffer is being sent.
+     * @param timestampMs   The timestamp of the buffer is being sent.
      * @param handle        The native handle to the allocated buffer. handle
      *                      should be cloned before use.
      * @param buffer        The received buffer.
@@ -142,10 +133,10 @@
      *         NO_MEMORY when there is no memory.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus receive(ConnectionId connectionId,
+    BufferPoolStatus receive(ConnectionId connectionId,
                          TransactionId transactionId,
                          BufferId bufferId,
-                         int64_t timestampUs,
+                         int64_t timestampMs,
                           native_handle_t **handle,
                          std::shared_ptr<BufferPoolData> *buffer);
 
@@ -156,17 +147,17 @@
      * @param receiverId    The id of the receiving connection.
      * @param buffer        to transfer
      * @param transactionId Id of the transfer transaction.
-     * @param timestampUs   The timestamp of the buffer transaction is being
+     * @param timestampMs   The timestamp of the buffer transaction is being
      *                      posted.
      *
      * @return OK when a buffer transaction was posted successfully.
      *         NOT_FOUND when the sending connection was not found.
      *         CRITICAL_ERROR otherwise.
      */
-    ResultStatus postSend(ConnectionId receiverId,
+    BufferPoolStatus postSend(ConnectionId receiverId,
                           const std::shared_ptr<BufferPoolData> &buffer,
                           TransactionId *transactionId,
-                          int64_t *timestampUs);
+                          int64_t *timestampMs);
 
     /**
      *  Time out inactive lingering connections and close.
@@ -176,20 +167,16 @@
     /** Destructs the manager of buffer pool clients.  */
     ~ClientManager();
 private:
-    static sp<ClientManager> sInstance;
+    static std::shared_ptr<ClientManager> sInstance;
     static std::mutex sInstanceLock;
 
     class Impl;
     const std::unique_ptr<Impl> mImpl;
 
+    friend class ::ndk::SharedRefBase;
+
     ClientManager();
 };
 
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
 
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V2_0_CLIENTMANAGER_H
diff --git a/media/bufferpool/aidl/default/tests/Android.bp b/media/bufferpool/aidl/default/tests/Android.bp
new file mode 100644
index 0000000..549af57
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/Android.bp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetSingleTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "single.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetMultiTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "multi.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetCondTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "cond.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
diff --git a/media/bufferpool/aidl/default/tests/BufferpoolUnitTest.cpp b/media/bufferpool/aidl/default/tests/BufferpoolUnitTest.cpp
deleted file mode 100644
index b448405..0000000
--- a/media/bufferpool/aidl/default/tests/BufferpoolUnitTest.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2021 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_NDEBUG 0
-#define LOG_TAG "BufferpoolUnitTest"
-#include <utils/Log.h>
-
-#include <binder/ProcessState.h>
-#include <bufferpool/ClientManager.h>
-#include <gtest/gtest.h>
-#include <hidl/LegacySupport.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unordered_set>
-#include <vector>
-#include "allocator.h"
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::media::bufferpool::BufferPoolData;
-using android::hardware::media::bufferpool::V2_0::IClientManager;
-using android::hardware::media::bufferpool::V2_0::ResultStatus;
-using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
-
-using namespace android;
-
-// communication message types between processes.
-enum PipeCommand : int32_t {
-    INIT,
-    TRANSFER,
-    STOP,
-
-    INIT_OK,
-    INIT_ERROR,
-    TRANSFER_OK,
-    TRANSFER_ERROR,
-    STOP_OK,
-    STOP_ERROR,
-};
-
-// communication message between processes.
-union PipeMessage {
-    struct {
-        int32_t command;
-        int32_t memsetValue;
-        BufferId bufferId;
-        ConnectionId connectionId;
-        TransactionId transactionId;
-        int64_t timestampUs;
-    } data;
-    char array[0];
-};
-
-static int32_t kNumIterationCount = 10;
-
-class BufferpoolTest {
-  public:
-    BufferpoolTest() : mConnectionValid(false), mManager(nullptr), mAllocator(nullptr) {
-        mConnectionId = -1;
-        mReceiverId = -1;
-    }
-
-    ~BufferpoolTest() {
-        if (mConnectionValid) {
-            mManager->close(mConnectionId);
-        }
-    }
-
-  protected:
-    bool mConnectionValid;
-    ConnectionId mConnectionId;
-    ConnectionId mReceiverId;
-
-    android::sp<ClientManager> mManager;
-    std::shared_ptr<BufferPoolAllocator> mAllocator;
-
-    void setupBufferpoolManager();
-};
-
-void BufferpoolTest::setupBufferpoolManager() {
-    // retrieving per process bufferpool object sp<ClientManager>
-    mManager = ClientManager::getInstance();
-    ASSERT_NE(mManager, nullptr) << "unable to get ClientManager\n";
-
-    mAllocator = std::make_shared<TestBufferPoolAllocator>();
-    ASSERT_NE(mAllocator, nullptr) << "unable to create TestBufferPoolAllocator\n";
-
-    // set-up local bufferpool connection for sender
-    ResultStatus status = mManager->create(mAllocator, &mConnectionId);
-    ASSERT_EQ(status, ResultStatus::OK)
-            << "unable to set-up local bufferpool connection for sender\n";
-    mConnectionValid = true;
-}
-
-class BufferpoolUnitTest : public BufferpoolTest, public ::testing::Test {
-  public:
-    virtual void SetUp() override { setupBufferpoolManager(); }
-
-    virtual void TearDown() override {}
-};
-
-class BufferpoolFunctionalityTest : public BufferpoolTest, public ::testing::Test {
-  public:
-    virtual void SetUp() override {
-        mReceiverPid = -1;
-
-        ASSERT_TRUE(pipe(mCommandPipeFds) == 0) << "pipe connection failed for commandPipe\n";
-        ASSERT_TRUE(pipe(mResultPipeFds) == 0) << "pipe connection failed for resultPipe\n";
-
-        mReceiverPid = fork();
-        ASSERT_TRUE(mReceiverPid >= 0) << "fork failed\n";
-
-        if (mReceiverPid == 0) {
-            doReceiver();
-            // In order to ignore gtest behaviour, wait for being killed from tearDown
-            pause();
-        }
-        setupBufferpoolManager();
-    }
-
-    virtual void TearDown() override {
-        if (mReceiverPid > 0) {
-            kill(mReceiverPid, SIGKILL);
-            int wstatus;
-            wait(&wstatus);
-        }
-    }
-
-  protected:
-    pid_t mReceiverPid;
-    int mCommandPipeFds[2];
-    int mResultPipeFds[2];
-
-    bool sendMessage(int* pipes, const PipeMessage& message) {
-        int ret = write(pipes[1], message.array, sizeof(PipeMessage));
-        return ret == sizeof(PipeMessage);
-    }
-
-    bool receiveMessage(int* pipes, PipeMessage* message) {
-        int ret = read(pipes[0], message->array, sizeof(PipeMessage));
-        return ret == sizeof(PipeMessage);
-    }
-
-    void doReceiver();
-};
-
-void BufferpoolFunctionalityTest::doReceiver() {
-    // Configures the threadpool used for handling incoming RPC calls in this process.
-    configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
-    bool receiverRunning = true;
-    while (receiverRunning) {
-        PipeMessage message;
-        receiveMessage(mCommandPipeFds, &message);
-        ResultStatus err = ResultStatus::OK;
-        switch (message.data.command) {
-            case PipeCommand::INIT: {
-                // receiver manager creation
-                mManager = ClientManager::getInstance();
-                if (!mManager) {
-                    message.data.command = PipeCommand::INIT_ERROR;
-                    sendMessage(mResultPipeFds, message);
-                    return;
-                }
-
-                android::status_t status = mManager->registerAsService();
-                if (status != android::OK) {
-                    message.data.command = PipeCommand::INIT_ERROR;
-                    sendMessage(mResultPipeFds, message);
-                    return;
-                }
-                message.data.command = PipeCommand::INIT_OK;
-                sendMessage(mResultPipeFds, message);
-                break;
-            }
-            case PipeCommand::TRANSFER: {
-                native_handle_t* receiveHandle = nullptr;
-                std::shared_ptr<BufferPoolData> receiveBuffer;
-                err = mManager->receive(message.data.connectionId, message.data.transactionId,
-                                        message.data.bufferId, message.data.timestampUs,
-                                        &receiveHandle, &receiveBuffer);
-                if (err != ResultStatus::OK) {
-                    message.data.command = PipeCommand::TRANSFER_ERROR;
-                    sendMessage(mResultPipeFds, message);
-                    return;
-                }
-                if (!TestBufferPoolAllocator::Verify(receiveHandle, message.data.memsetValue)) {
-                    message.data.command = PipeCommand::TRANSFER_ERROR;
-                    sendMessage(mResultPipeFds, message);
-                    return;
-                }
-                if (receiveHandle) {
-                    native_handle_close(receiveHandle);
-                    native_handle_delete(receiveHandle);
-                }
-                receiveHandle = nullptr;
-                receiveBuffer.reset();
-                message.data.command = PipeCommand::TRANSFER_OK;
-                sendMessage(mResultPipeFds, message);
-                break;
-            }
-            case PipeCommand::STOP: {
-                err = mManager->close(message.data.connectionId);
-                if (err != ResultStatus::OK) {
-                    message.data.command = PipeCommand::STOP_ERROR;
-                    sendMessage(mResultPipeFds, message);
-                    return;
-                }
-                message.data.command = PipeCommand::STOP_OK;
-                sendMessage(mResultPipeFds, message);
-                receiverRunning = false;
-                break;
-            }
-            default:
-                ALOGE("unknown command. try again");
-                break;
-        }
-    }
-}
-
-// Buffer allocation test.
-// Check whether each buffer allocation is done successfully with unique buffer id.
-TEST_F(BufferpoolUnitTest, AllocateBuffer) {
-    std::vector<uint8_t> vecParams;
-    getTestAllocatorParams(&vecParams);
-
-    std::vector<std::shared_ptr<BufferPoolData>> buffers{};
-    std::vector<native_handle_t*> allocHandle{};
-    ResultStatus status;
-    for (int i = 0; i < kNumIterationCount; ++i) {
-        native_handle_t* handle = nullptr;
-        std::shared_ptr<BufferPoolData> buffer{};
-        status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
-        ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << "iteration";
-
-        buffers.push_back(std::move(buffer));
-        if (handle) {
-            allocHandle.push_back(std::move(handle));
-        }
-    }
-
-    for (int i = 0; i < kNumIterationCount; ++i) {
-        for (int j = i + 1; j < kNumIterationCount; ++j) {
-            ASSERT_TRUE(buffers[i]->mId != buffers[j]->mId) << "allocated buffers are not unique";
-        }
-    }
-    // delete the buffer handles
-    for (auto handle : allocHandle) {
-        native_handle_close(handle);
-        native_handle_delete(handle);
-    }
-    // clear the vectors
-    buffers.clear();
-    allocHandle.clear();
-}
-
-// Buffer recycle test.
-// Check whether de-allocated buffers are recycled.
-TEST_F(BufferpoolUnitTest, RecycleBuffer) {
-    std::vector<uint8_t> vecParams;
-    getTestAllocatorParams(&vecParams);
-
-    ResultStatus status;
-    std::vector<BufferId> bid{};
-    std::vector<native_handle_t*> allocHandle{};
-    for (int i = 0; i < kNumIterationCount; ++i) {
-        native_handle_t* handle = nullptr;
-        std::shared_ptr<BufferPoolData> buffer;
-        status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
-        ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << "iteration";
-
-        bid.push_back(buffer->mId);
-        if (handle) {
-            allocHandle.push_back(std::move(handle));
-        }
-        buffer.reset();
-    }
-
-    std::unordered_set<BufferId> set(bid.begin(), bid.end());
-    ASSERT_EQ(set.size(), 1) << "buffers are not recycled properly";
-
-    // delete the buffer handles
-    for (auto handle : allocHandle) {
-        native_handle_close(handle);
-        native_handle_delete(handle);
-    }
-    allocHandle.clear();
-}
-
-// Validate cache evict and invalidate APIs.
-TEST_F(BufferpoolUnitTest, FlushTest) {
-    std::vector<uint8_t> vecParams;
-    getTestAllocatorParams(&vecParams);
-
-    ResultStatus status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
-    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS && mReceiverId == mConnectionId);
-
-    // testing empty flush
-    status = mManager->flush(mConnectionId);
-    ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;
-
-    std::vector<std::shared_ptr<BufferPoolData>> senderBuffer{};
-    std::vector<native_handle_t*> allocHandle{};
-    std::vector<TransactionId> tid{};
-    std::vector<int64_t> timestampUs{};
-
-    std::map<TransactionId, BufferId> bufferMap{};
-
-    for (int i = 0; i < kNumIterationCount; i++) {
-        int64_t postUs;
-        TransactionId transactionId;
-        native_handle_t* handle = nullptr;
-        std::shared_ptr<BufferPoolData> buffer{};
-        status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
-        ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << " iteration";
-
-        ASSERT_TRUE(TestBufferPoolAllocator::Fill(handle, i));
-
-        status = mManager->postSend(mReceiverId, buffer, &transactionId, &postUs);
-        ASSERT_EQ(status, ResultStatus::OK) << "unable to post send transaction on bufferpool";
-
-        timestampUs.push_back(postUs);
-        tid.push_back(transactionId);
-        bufferMap.insert({transactionId, buffer->mId});
-
-        senderBuffer.push_back(std::move(buffer));
-        if (handle) {
-            allocHandle.push_back(std::move(handle));
-        }
-        buffer.reset();
-    }
-
-    status = mManager->flush(mConnectionId);
-    ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;
-
-    std::shared_ptr<BufferPoolData> receiverBuffer{};
-    native_handle_t* recvHandle = nullptr;
-    for (int i = 0; i < kNumIterationCount; i++) {
-        status = mManager->receive(mReceiverId, tid[i], senderBuffer[i]->mId, timestampUs[i],
-                                   &recvHandle, &receiverBuffer);
-        ASSERT_EQ(status, ResultStatus::OK) << "receive failed for buffer " << senderBuffer[i]->mId;
-
-        // find the buffer id from transaction id
-        auto findIt = bufferMap.find(tid[i]);
-        ASSERT_NE(findIt, bufferMap.end()) << "inconsistent buffer mapping";
-
-        // buffer id received must be same as the buffer id sent
-        ASSERT_EQ(findIt->second, receiverBuffer->mId) << "invalid buffer received";
-
-        ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, i))
-                << "Message received not same as that sent";
-
-        bufferMap.erase(findIt);
-        if (recvHandle) {
-            native_handle_close(recvHandle);
-            native_handle_delete(recvHandle);
-        }
-        recvHandle = nullptr;
-        receiverBuffer.reset();
-    }
-
-    ASSERT_EQ(bufferMap.size(), 0) << "buffers received is less than the number of buffers sent";
-
-    for (auto handle : allocHandle) {
-        native_handle_close(handle);
-        native_handle_delete(handle);
-    }
-    allocHandle.clear();
-    senderBuffer.clear();
-    timestampUs.clear();
-}
-
-// Buffer transfer test between processes.
-TEST_F(BufferpoolFunctionalityTest, TransferBuffer) {
-    // initialize the receiver
-    PipeMessage message;
-    message.data.command = PipeCommand::INIT;
-    sendMessage(mCommandPipeFds, message);
-    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-    ASSERT_EQ(message.data.command, PipeCommand::INIT_OK) << "receiver init failed";
-
-    android::sp<IClientManager> receiver = IClientManager::getService();
-    ASSERT_NE(receiver, nullptr) << "getService failed for receiver\n";
-
-    ConnectionId receiverId;
-    ResultStatus status = mManager->registerSender(receiver, mConnectionId, &receiverId);
-    ASSERT_EQ(status, ResultStatus::OK)
-            << "registerSender failed for connection id " << mConnectionId << "\n";
-
-    std::vector<uint8_t> vecParams;
-    getTestAllocatorParams(&vecParams);
-
-    for (int i = 0; i < kNumIterationCount; ++i) {
-        native_handle_t* handle = nullptr;
-        std::shared_ptr<BufferPoolData> buffer;
-        status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
-        ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << "iteration";
-
-        ASSERT_TRUE(TestBufferPoolAllocator::Fill(handle, i))
-                << "Fill fail for buffer handle " << handle << "\n";
-
-        // send the buffer to the receiver
-        int64_t postUs;
-        TransactionId transactionId;
-        status = mManager->postSend(receiverId, buffer, &transactionId, &postUs);
-        ASSERT_EQ(status, ResultStatus::OK)
-                << "postSend failed for receiver " << receiverId << "\n";
-
-        // PipeMessage message;
-        message.data.command = PipeCommand::TRANSFER;
-        message.data.memsetValue = i;
-        message.data.bufferId = buffer->mId;
-        message.data.connectionId = receiverId;
-        message.data.transactionId = transactionId;
-        message.data.timestampUs = postUs;
-        sendMessage(mCommandPipeFds, message);
-        // delete buffer handle
-        if (handle) {
-            native_handle_close(handle);
-            native_handle_delete(handle);
-        }
-        ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-        ASSERT_EQ(message.data.command, PipeCommand::TRANSFER_OK)
-                << "received error during buffer transfer\n";
-    }
-    message.data.command = PipeCommand::STOP;
-    sendMessage(mCommandPipeFds, message);
-    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-    ASSERT_EQ(message.data.command, PipeCommand::STOP_OK)
-            << "received error during buffer transfer\n";
-}
-
-/* Validate bufferpool for following corner cases:
- 1. invalid connectionID
- 2. invalid receiver
- 3. when sender is not registered
- 4. when connection is closed
-*/
-// TODO: Enable when the issue in b/212196495 is fixed
-TEST_F(BufferpoolFunctionalityTest, DISABLED_ValidityTest) {
-    std::vector<uint8_t> vecParams;
-    getTestAllocatorParams(&vecParams);
-
-    std::shared_ptr<BufferPoolData> senderBuffer;
-    native_handle_t* allocHandle = nullptr;
-
-    // call allocate() on a random connection id
-    ConnectionId randomId = rand();
-    ResultStatus status = mManager->allocate(randomId, vecParams, &allocHandle, &senderBuffer);
-    EXPECT_TRUE(status == ResultStatus::NOT_FOUND);
-
-    // initialize the receiver
-    PipeMessage message;
-    message.data.command = PipeCommand::INIT;
-    sendMessage(mCommandPipeFds, message);
-    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-    ASSERT_EQ(message.data.command, PipeCommand::INIT_OK) << "receiver init failed";
-
-    allocHandle = nullptr;
-    senderBuffer.reset();
-    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);
-
-    ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
-
-    // send buffers w/o registering sender
-    int64_t postUs;
-    TransactionId transactionId;
-
-    // random receiver
-    status = mManager->postSend(randomId, senderBuffer, &transactionId, &postUs);
-    ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on random receiver";
-
-    // establish connection
-    android::sp<IClientManager> receiver = IClientManager::getService();
-    ASSERT_NE(receiver, nullptr) << "getService failed for receiver\n";
-
-    ConnectionId receiverId;
-    status = mManager->registerSender(receiver, mConnectionId, &receiverId);
-    ASSERT_EQ(status, ResultStatus::OK)
-            << "registerSender failed for connection id " << mConnectionId << "\n";
-
-    allocHandle = nullptr;
-    senderBuffer.reset();
-    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);
-    ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for connection " << mConnectionId;
-
-    ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x88));
-
-    // send the buffer to the receiver
-    status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
-    ASSERT_EQ(status, ResultStatus::OK) << "postSend failed for receiver " << receiverId << "\n";
-
-    // PipeMessage message;
-    message.data.command = PipeCommand::TRANSFER;
-    message.data.memsetValue = 0x88;
-    message.data.bufferId = senderBuffer->mId;
-    message.data.connectionId = receiverId;
-    message.data.transactionId = transactionId;
-    message.data.timestampUs = postUs;
-    sendMessage(mCommandPipeFds, message);
-    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-    ASSERT_EQ(message.data.command, PipeCommand::TRANSFER_OK)
-            << "received error during buffer transfer\n";
-
-    if (allocHandle) {
-        native_handle_close(allocHandle);
-        native_handle_delete(allocHandle);
-    }
-
-    message.data.command = PipeCommand::STOP;
-    sendMessage(mCommandPipeFds, message);
-    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
-    ASSERT_EQ(message.data.command, PipeCommand::STOP_OK)
-            << "received error during buffer transfer\n";
-
-    // try to send msg to closed connection
-    status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
-    ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on closed connection";
-}
-
-int main(int argc, char** argv) {
-    android::hardware::details::setTrebleTestingOverride(true);
-    ::testing::InitGoogleTest(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGV("Test result = %d\n", status);
-    return status;
-}
diff --git a/media/bufferpool/aidl/default/tests/allocator.cpp b/media/bufferpool/aidl/default/tests/allocator.cpp
index 25b08ef..16b33a6 100644
--- a/media/bufferpool/aidl/default/tests/allocator.cpp
+++ b/media/bufferpool/aidl/default/tests/allocator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -139,7 +139,7 @@
 }
 
 
-ResultStatus TestBufferPoolAllocator::allocate(
+BufferPoolStatus TestBufferPoolAllocator::allocate(
     const std::vector<uint8_t> &params,
     std::shared_ptr<BufferPoolAllocation> *alloc,
     size_t *allocSize) {
diff --git a/media/bufferpool/aidl/default/tests/allocator.h b/media/bufferpool/aidl/default/tests/allocator.h
index 862d1a5..7e7203f 100644
--- a/media/bufferpool/aidl/default/tests/allocator.h
+++ b/media/bufferpool/aidl/default/tests/allocator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,17 +14,18 @@
  * limitations under the License.
  */
 
-#ifndef VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
-#define VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
+#pragma once
 
 #include <pthread.h>
-#include <bufferpool/BufferPoolTypes.h>
+#include <bufferpool2/BufferPoolTypes.h>
 
-using android::hardware::media::bufferpool::V2_0::ResultStatus;
-using android::hardware::media::bufferpool::V2_0::implementation::
+using aidl::android::hardware::media::bufferpool2::implementation::
+    BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::
     BufferPoolAllocation;
-using android::hardware::media::bufferpool::V2_0::implementation::
+using aidl::android::hardware::media::bufferpool2::implementation::
     BufferPoolAllocator;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
 
 struct IpcMutex {
   pthread_mutex_t lock;
@@ -44,7 +45,7 @@
 
   ~TestBufferPoolAllocator() override {}
 
-  ResultStatus allocate(const std::vector<uint8_t> &params,
+  BufferPoolStatus allocate(const std::vector<uint8_t> &params,
                         std::shared_ptr<BufferPoolAllocation> *alloc,
                         size_t *allocSize) override;
 
@@ -60,9 +61,7 @@
   static bool UnmapMemoryForMutex(void *mem);
 };
 
-// retrieve buffer allocator paramters
+// retrieve buffer allocator parameters
 void getTestAllocatorParams(std::vector<uint8_t> *params);
 
 void getIpcMutexParams(std::vector<uint8_t> *params);
-
-#endif  // VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
diff --git a/media/bufferpool/aidl/default/tests/cond.cpp b/media/bufferpool/aidl/default/tests/cond.cpp
index 21beea8..6d469ce 100644
--- a/media/bufferpool/aidl/default/tests/cond.cpp
+++ b/media/bufferpool/aidl/default/tests/cond.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -18,35 +18,36 @@
 
 #include <gtest/gtest.h>
 
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
 #include <android-base/logging.h>
-#include <binder/ProcessState.h>
-#include <bufferpool/ClientManager.h>
+#include <bufferpool2/ClientManager.h>
+
 #include <errno.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-#include <hidl/Status.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+
 #include <iostream>
 #include <memory>
 #include <vector>
+
 #include "allocator.h"
 
-using android::hardware::configureRpcThreadpool;
-using android::hardware::hidl_handle;
-using android::hardware::media::bufferpool::V2_0::IClientManager;
-using android::hardware::media::bufferpool::V2_0::ResultStatus;
-using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
-using android::hardware::media::bufferpool::BufferPoolData;
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
 
 namespace {
 
+const std::string testInstance  = std::string() + ClientManager::descriptor + "/condtest";
+
 // communication message types between processes.
 enum PipeCommand : int32_t {
     INIT_OK = 0,
@@ -74,7 +75,7 @@
 class BufferpoolMultiTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    ResultStatus status;
+    BufferPoolStatus status;
     mReceiverPid = -1;
     mConnectionValid = false;
 
@@ -119,7 +120,7 @@
     RecordProperty("description", description);
   }
 
-  android::sp<ClientManager> mManager;
+  std::shared_ptr<ClientManager> mManager;
   std::shared_ptr<BufferPoolAllocator> mAllocator;
   bool mConnectionValid;
   ConnectionId mConnectionId;
@@ -138,7 +139,8 @@
   }
 
   void doReceiver() {
-    configureRpcThreadpool(1, false);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
     PipeMessage message;
     mManager = ClientManager::getInstance();
     if (!mManager) {
@@ -146,7 +148,11 @@
       sendMessage(mResultPipeFds, message);
       return;
     }
-    android::status_t status = mManager->registerAsService();
+    auto binder = mManager->asBinder();
+    AIBinder_forceDowngradeToSystemStability(binder.get());
+    binder_status_t status =
+        AServiceManager_addService(binder.get(), testInstance.c_str());
+    CHECK_EQ(status, STATUS_OK);
     if (status != android::OK) {
       message.data.command = PipeCommand::INIT_ERROR;
       sendMessage(mResultPipeFds, message);
@@ -162,7 +168,7 @@
       std::shared_ptr<BufferPoolData> rbuffer;
       void *mem = nullptr;
       IpcMutex *mutex = nullptr;
-      ResultStatus status = mManager->receive(
+      BufferPoolStatus status = mManager->receive(
           message.data.connectionId, message.data.transactionId,
           message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
       mManager->close(message.data.connectionId);
@@ -201,16 +207,22 @@
 
 // Buffer transfer test between processes.
 TEST_F(BufferpoolMultiTest, TransferBuffer) {
-  ResultStatus status;
+  BufferPoolStatus status;
   PipeMessage message;
 
   ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+  ABinderProcess_setThreadPoolMaxThreadCount(1);
+  ABinderProcess_startThreadPool();
 
-  android::sp<IClientManager> receiver = IClientManager::getService();
+
+  std::shared_ptr<IClientManager> receiver =
+      IClientManager::fromBinder(
+          ndk::SpAIBinder(AServiceManager_waitForService(testInstance.c_str())));
+  ASSERT_NE(receiver, nullptr);
   ConnectionId receiverId;
-  ASSERT_TRUE((bool)receiver);
 
-  status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+  bool isNew = true;
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
   ASSERT_TRUE(status == ResultStatus::OK);
   {
     native_handle_t *shandle = nullptr;
@@ -261,7 +273,6 @@
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-  android::hardware::details::setTrebleTestingOverride(true);
   ::testing::InitGoogleTest(&argc, argv);
   int status = RUN_ALL_TESTS();
   LOG(INFO) << "Test result = " << status;
diff --git a/media/bufferpool/aidl/default/tests/multi.cpp b/media/bufferpool/aidl/default/tests/multi.cpp
index 43b0a8c..8806eb0 100644
--- a/media/bufferpool/aidl/default/tests/multi.cpp
+++ b/media/bufferpool/aidl/default/tests/multi.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -18,34 +18,35 @@
 
 #include <gtest/gtest.h>
 
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
 #include <android-base/logging.h>
-#include <binder/ProcessState.h>
-#include <bufferpool/ClientManager.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-#include <hidl/Status.h>
+#include <bufferpool2/ClientManager.h>
+
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+
 #include <iostream>
 #include <memory>
 #include <vector>
+
 #include "allocator.h"
 
-using android::hardware::configureRpcThreadpool;
-using android::hardware::hidl_handle;
-using android::hardware::media::bufferpool::V2_0::IClientManager;
-using android::hardware::media::bufferpool::V2_0::ResultStatus;
-using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
-using android::hardware::media::bufferpool::BufferPoolData;
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
 
 namespace {
 
+const std::string testInstance  = std::string() + ClientManager::descriptor + "/multitest";
+
 // communication message types between processes.
 enum PipeCommand : int32_t {
     INIT_OK = 0,
@@ -71,7 +72,7 @@
 class BufferpoolMultiTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    ResultStatus status;
+    BufferPoolStatus status;
     mReceiverPid = -1;
     mConnectionValid = false;
 
@@ -87,7 +88,6 @@
       // tearDown
       pause();
     }
-
     mManager = ClientManager::getInstance();
     ASSERT_NE(mManager, nullptr);
 
@@ -116,7 +116,7 @@
     RecordProperty("description", description);
   }
 
-  android::sp<ClientManager> mManager;
+  std::shared_ptr<ClientManager> mManager;
   std::shared_ptr<BufferPoolAllocator> mAllocator;
   bool mConnectionValid;
   ConnectionId mConnectionId;
@@ -135,7 +135,8 @@
   }
 
   void doReceiver() {
-    configureRpcThreadpool(1, false);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
     PipeMessage message;
     mManager = ClientManager::getInstance();
     if (!mManager) {
@@ -143,7 +144,11 @@
       sendMessage(mResultPipeFds, message);
       return;
     }
-    android::status_t status = mManager->registerAsService();
+    auto binder = mManager->asBinder();
+    AIBinder_forceDowngradeToSystemStability(binder.get());
+    binder_status_t status =
+        AServiceManager_addService(binder.get(), testInstance.c_str());
+    CHECK_EQ(status, STATUS_OK);
     if (status != android::OK) {
       message.data.command = PipeCommand::INIT_ERROR;
       sendMessage(mResultPipeFds, message);
@@ -156,7 +161,7 @@
     {
       native_handle_t *rhandle = nullptr;
       std::shared_ptr<BufferPoolData> rbuffer;
-      ResultStatus status = mManager->receive(
+      BufferPoolStatus status = mManager->receive(
           message.data.connectionId, message.data.transactionId,
           message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
       mManager->close(message.data.connectionId);
@@ -182,16 +187,20 @@
 
 // Buffer transfer test between processes.
 TEST_F(BufferpoolMultiTest, TransferBuffer) {
-  ResultStatus status;
+  BufferPoolStatus status;
   PipeMessage message;
 
   ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+  ABinderProcess_setThreadPoolMaxThreadCount(1);
+  ABinderProcess_startThreadPool();
 
-  android::sp<IClientManager> receiver = IClientManager::getService();
+  std::shared_ptr<IClientManager> receiver = IClientManager::fromBinder(ndk::SpAIBinder(
+      AServiceManager_waitForService(testInstance.c_str())));
+  ASSERT_NE(receiver, nullptr);
   ConnectionId receiverId;
-  ASSERT_TRUE((bool)receiver);
 
-  status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+  bool isNew = true;
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
   ASSERT_TRUE(status == ResultStatus::OK);
   {
     native_handle_t *shandle = nullptr;
@@ -227,7 +236,6 @@
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-  android::hardware::details::setTrebleTestingOverride(true);
   ::testing::InitGoogleTest(&argc, argv);
   int status = RUN_ALL_TESTS();
   LOG(INFO) << "Test result = " << status;
diff --git a/media/bufferpool/aidl/default/tests/single.cpp b/media/bufferpool/aidl/default/tests/single.cpp
index 1e9027b..66aa5e9 100644
--- a/media/bufferpool/aidl/default/tests/single.cpp
+++ b/media/bufferpool/aidl/default/tests/single.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -20,24 +20,19 @@
 
 #include <android-base/logging.h>
 #include <binder/ProcessState.h>
-#include <bufferpool/ClientManager.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-#include <hidl/Status.h>
+#include <bufferpool2/ClientManager.h>
 #include <unistd.h>
 #include <iostream>
 #include <memory>
 #include <vector>
 #include "allocator.h"
 
-using android::hardware::hidl_handle;
-using android::hardware::media::bufferpool::V2_0::ResultStatus;
-using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
-using android::hardware::media::bufferpool::BufferPoolData;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
 
 namespace {
 
@@ -51,7 +46,7 @@
 class BufferpoolSingleTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    ResultStatus status;
+    BufferPoolStatus status;
     mConnectionValid = false;
 
     mManager = ClientManager::getInstance();
@@ -65,8 +60,9 @@
 
     mConnectionValid = true;
 
-    status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
-    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS &&
+    bool isNew = true;
+    status = mManager->registerSender(mManager, mConnectionId, &mReceiverId, &isNew);
+    ASSERT_TRUE(status == ResultStatus::OK && isNew == false &&
                 mReceiverId == mConnectionId);
   }
 
@@ -81,7 +77,7 @@
     RecordProperty("description", description);
   }
 
-  android::sp<ClientManager> mManager;
+  std::shared_ptr<ClientManager> mManager;
   std::shared_ptr<BufferPoolAllocator> mAllocator;
   bool mConnectionValid;
   ConnectionId mConnectionId;
@@ -93,7 +89,7 @@
 // Check whether each buffer allocation is done successfully with
 // unique buffer id.
 TEST_F(BufferpoolSingleTest, AllocateBuffer) {
-  ResultStatus status;
+  BufferPoolStatus status;
   std::vector<uint8_t> vecParams;
   getTestAllocatorParams(&vecParams);
 
@@ -118,7 +114,7 @@
 // Buffer recycle test.
 // Check whether de-allocated buffers are recycled.
 TEST_F(BufferpoolSingleTest, RecycleBuffer) {
-  ResultStatus status;
+  BufferPoolStatus status;
   std::vector<uint8_t> vecParams;
   getTestAllocatorParams(&vecParams);
 
@@ -143,7 +139,7 @@
 // Buffer transfer test.
 // Check whether buffer is transferred to another client successfully.
 TEST_F(BufferpoolSingleTest, TransferBuffer) {
-  ResultStatus status;
+  BufferPoolStatus status;
   std::vector<uint8_t> vecParams;
   getTestAllocatorParams(&vecParams);
   std::shared_ptr<BufferPoolData> sbuffer, rbuffer;
@@ -151,14 +147,14 @@
   native_handle_t *recvHandle = nullptr;
 
   TransactionId transactionId;
-  int64_t postUs;
+  int64_t postMs;
 
   status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &sbuffer);
   ASSERT_TRUE(status == ResultStatus::OK);
   ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
-  status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postUs);
+  status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postMs);
   ASSERT_TRUE(status == ResultStatus::OK);
-  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs,
+  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postMs,
                              &recvHandle, &rbuffer);
   EXPECT_TRUE(status == ResultStatus::OK);
   ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));