diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 56b17ae..6c39bbf 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -177,8 +177,6 @@
 
         "BitTube.cpp",
         "BLASTBufferQueue.cpp",
-        "BufferHubConsumer.cpp",
-        "BufferHubProducer.cpp",
         "BufferItemConsumer.cpp",
         "ConsumerBase.cpp",
         "CpuConsumer.cpp",
@@ -216,9 +214,6 @@
 
     shared_libs: [
         "libbinder",
-        "libbufferhub",
-        "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
-        "libpdx_default_transport",
     ],
 
     export_shared_lib_headers: [
@@ -229,24 +224,6 @@
         "libgui_aidl_headers",
     ],
 
-    // bufferhub is not used when building libgui for vendors
-    target: {
-        vendor: {
-            cflags: [
-                "-DNO_BUFFERHUB",
-            ],
-            exclude_srcs: [
-                "BufferHubConsumer.cpp",
-                "BufferHubProducer.cpp",
-            ],
-            exclude_shared_libs: [
-                "libbufferhub",
-                "libbufferhubqueue",
-                "libpdx_default_transport",
-            ],
-        },
-    },
-
     aidl: {
         export_aidl_headers: true,
     },
@@ -276,7 +253,6 @@
     min_sdk_version: "29",
 
     cflags: [
-        "-DNO_BUFFERHUB",
         "-DNO_BINDER",
     ],
 
diff --git a/libs/gui/BufferHubConsumer.cpp b/libs/gui/BufferHubConsumer.cpp
deleted file mode 100644
index b5cdeb2..0000000
--- a/libs/gui/BufferHubConsumer.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <gui/BufferHubConsumer.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubConsumer> BufferHubConsumer::Create(const std::shared_ptr<ConsumerQueue>& queue) {
-    sp<BufferHubConsumer> consumer = new BufferHubConsumer;
-    consumer->mQueue = queue;
-    return consumer;
-}
-
-/* static */ sp<BufferHubConsumer> BufferHubConsumer::Create(ConsumerQueueParcelable parcelable) {
-    if (!parcelable.IsValid()) {
-        ALOGE("BufferHubConsumer::Create: Invalid consumer parcelable.");
-        return nullptr;
-    }
-
-    sp<BufferHubConsumer> consumer = new BufferHubConsumer;
-    consumer->mQueue = ConsumerQueue::Import(parcelable.TakeChannelHandle());
-    return consumer;
-}
-
-status_t BufferHubConsumer::acquireBuffer(BufferItem* /*buffer*/, nsecs_t /*presentWhen*/,
-                                          uint64_t /*maxFrameNumber*/) {
-    ALOGE("BufferHubConsumer::acquireBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::detachBuffer(int /*slot*/) {
-    ALOGE("BufferHubConsumer::detachBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::attachBuffer(int* /*outSlot*/, const sp<GraphicBuffer>& /*buffer*/) {
-    ALOGE("BufferHubConsumer::attachBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::releaseBuffer(int /*buf*/, uint64_t /*frameNumber*/,
-                                          EGLDisplay /*display*/, EGLSyncKHR /*fence*/,
-                                          const sp<Fence>& /*releaseFence*/) {
-    ALOGE("BufferHubConsumer::releaseBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::consumerConnect(const sp<IConsumerListener>& /*consumer*/,
-                                            bool /*controlledByApp*/) {
-    ALOGE("BufferHubConsumer::consumerConnect: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::consumerDisconnect() {
-    ALOGE("BufferHubConsumer::consumerDisconnect: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::getReleasedBuffers(uint64_t* /*slotMask*/) {
-    ALOGE("BufferHubConsumer::getReleasedBuffers: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferSize: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxBufferCount(int /*bufferCount*/) {
-    ALOGE("BufferHubConsumer::setMaxBufferCount: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxAcquiredBufferCount(int /*maxAcquiredBuffers*/) {
-    ALOGE("BufferHubConsumer::setMaxAcquiredBufferCount: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::setConsumerName(const String8& /*name*/) {
-    ALOGE("BufferHubConsumer::setConsumerName: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferFormat(PixelFormat /*defaultFormat*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferFormat: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferDataSpace(android_dataspace /*defaultDataSpace*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferDataSpace: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerUsageBits(uint64_t /*usage*/) {
-    ALOGE("BufferHubConsumer::setConsumerUsageBits: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerIsProtected(bool /*isProtected*/) {
-    ALOGE("BufferHubConsumer::setConsumerIsProtected: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setTransformHint(uint32_t /*hint*/) {
-    ALOGE("BufferHubConsumer::setTransformHint: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getSidebandStream(sp<NativeHandle>* /*outStream*/) const {
-    ALOGE("BufferHubConsumer::getSidebandStream: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getOccupancyHistory(
-        bool /*forceFlush*/, std::vector<OccupancyTracker::Segment>* /*outHistory*/) {
-    ALOGE("BufferHubConsumer::getOccupancyHistory: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::discardFreeBuffers() {
-    ALOGE("BufferHubConsumer::discardFreeBuffers: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::dumpState(const String8& /*prefix*/, String8* /*outResult*/) const {
-    ALOGE("BufferHubConsumer::dumpState: not implemented.");
-    return INVALID_OPERATION;
-}
-
-IBinder* BufferHubConsumer::onAsBinder() {
-    ALOGE("BufferHubConsumer::onAsBinder: BufferHubConsumer should never be used as an Binder "
-          "object.");
-    return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
deleted file mode 100644
index 1f71e23..0000000
--- a/libs/gui/BufferHubProducer.cpp
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <dvr/dvr_api.h>
-#include <gui/BufferHubProducer.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <system/window.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) {
-    sp<BufferHubProducer> producer = new BufferHubProducer;
-    producer->queue_ = queue;
-    return producer;
-}
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) {
-    if (!parcelable.IsValid()) {
-        ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
-        return nullptr;
-    }
-
-    sp<BufferHubProducer> producer = new BufferHubProducer;
-    producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
-    return producer;
-}
-
-status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
-    ALOGV("requestBuffer: slot=%d", slot);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("requestBuffer: BufferHubProducer has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (buffers_[slot].mGraphicBuffer != nullptr) {
-        ALOGE("requestBuffer: slot %d is not empty.", slot);
-        return BAD_VALUE;
-    } else if (buffers_[slot].mProducerBuffer == nullptr) {
-        ALOGE("requestBuffer: slot %d is not dequeued.", slot);
-        return BAD_VALUE;
-    }
-
-    const auto& producer_buffer = buffers_[slot].mProducerBuffer;
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-
-    buffers_[slot].mGraphicBuffer = graphic_buffer;
-    buffers_[slot].mRequestBufferCalled = true;
-
-    *buf = graphic_buffer;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) {
-    ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (max_dequeued_buffers <= 0 ||
-        max_dequeued_buffers >
-                int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
-        ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers,
-              BufferHubQueue::kMaxQueueCapacity);
-        return BAD_VALUE;
-    }
-
-    // The new dequeued_buffers count should not be violated by the number
-    // of currently dequeued buffers.
-    int dequeued_count = 0;
-    for (const auto& buf : buffers_) {
-        if (buf.mBufferState.isDequeued()) {
-            dequeued_count++;
-        }
-    }
-    if (dequeued_count > max_dequeued_buffers) {
-        ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers"
-              "count (%d) exceeds the current dequeued buffer count (%d)",
-              max_dequeued_buffers, dequeued_count);
-        return BAD_VALUE;
-    }
-
-    max_dequeued_buffer_count_ = max_dequeued_buffers;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAsyncMode(bool async) {
-    if (async) {
-        // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
-        // automatically and behaves differently from IGraphicBufferConsumer. Thus,
-        // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
-        // to prevent dequeueBuffer from being blocking) technically does not apply
-        // here.
-        //
-        // In Daydream, non-blocking producer side dequeue is guaranteed by careful
-        // buffer consumer implementations. In another word, BufferHubQueue based
-        // dequeueBuffer should never block whether setAsyncMode(true) is set or
-        // not.
-        //
-        // See: IGraphicBufferProducer::setAsyncMode and
-        // BufferQueueProducer::setAsyncMode for more about original implementation.
-        ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
-              "asynchronous. This call makes no effact.");
-        return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width,
-                                          uint32_t height, PixelFormat format, uint64_t usage,
-                                          uint64_t* /*outBufferAge*/,
-                                          FrameEventHistoryDelta* /* out_timestamps */) {
-    ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage);
-
-    status_t ret;
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("dequeueBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    const uint32_t kLayerCount = 1;
-    if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
-        // Lazy allocation. When the capacity of |queue_| has not reached
-        // |max_dequeued_buffer_count_|, allocate new buffer.
-        // TODO(jwcai) To save memory, the really reasonable thing to do is to go
-        // over existing slots and find first existing one to dequeue.
-        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
-        if (ret < 0) return ret;
-    }
-
-    size_t slot = 0;
-    std::shared_ptr<ProducerBuffer> producer_buffer;
-
-    for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
-        LocalHandle fence;
-        auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
-        if (!buffer_status) return NO_MEMORY;
-
-        producer_buffer = buffer_status.take();
-        if (!producer_buffer) return NO_MEMORY;
-
-        if (width == producer_buffer->width() && height == producer_buffer->height() &&
-            uint32_t(format) == producer_buffer->format()) {
-            // The producer queue returns a producer buffer matches the request.
-            break;
-        }
-
-        // Needs reallocation.
-        // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
-        ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
-              "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
-              "re-allocattion.",
-              width, height, format, slot, producer_buffer->width(), producer_buffer->height(),
-              producer_buffer->format());
-        // Mark the slot as reallocating, so that later we can set
-        // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
-        buffers_[slot].mIsReallocating = true;
-
-        // Remove the old buffer once the allocation before allocating its
-        // replacement.
-        RemoveBuffer(slot);
-
-        // Allocate a new producer buffer with new buffer configs. Note that if
-        // there are already multiple buffers in the queue, the next one returned
-        // from |queue_->Dequeue| may not be the new buffer we just reallocated.
-        // Retry up to BufferHubQueue::kMaxQueueCapacity times.
-        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
-        if (ret < 0) return ret;
-    }
-
-    // With the BufferHub backed solution. Buffer slot returned from
-    // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
-    // It's either in free state (if the buffer has never been used before) or
-    // in queued state (if the buffer has been dequeued and queued back to
-    // BufferHubQueue).
-    LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
-                         !buffers_[slot].mBufferState.isQueued()),
-                        "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
-                        buffers_[slot].mBufferState.string());
-
-    buffers_[slot].mBufferState.freeQueued();
-    buffers_[slot].mBufferState.dequeue();
-    ALOGV("dequeueBuffer: slot=%zu", slot);
-
-    // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
-    // just need to exopose that through |BufferHubQueue| once we need fence.
-    *out_fence = Fence::NO_FENCE;
-    *out_slot = int(slot);
-    ret = NO_ERROR;
-
-    if (buffers_[slot].mIsReallocating) {
-        ret |= BUFFER_NEEDS_REALLOCATION;
-        buffers_[slot].mIsReallocating = false;
-    }
-
-    return ret;
-}
-
-status_t BufferHubProducer::detachBuffer(int slot) {
-    ALOGV("detachBuffer: slot=%d", slot);
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    return DetachBufferLocked(static_cast<size_t>(slot));
-}
-
-status_t BufferHubProducer::DetachBufferLocked(size_t slot) {
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("detachBuffer: BufferHubProducer is not connected.");
-        return NO_INIT;
-    }
-
-    if (slot >= static_cast<size_t>(max_buffer_count_)) {
-        ALOGE("detachBuffer: slot index %zu out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("detachBuffer: slot %zu is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mRequestBufferCalled) {
-        ALOGE("detachBuffer: buffer in slot %zu has not been requested", slot);
-        return BAD_VALUE;
-    }
-    std::shared_ptr<ProducerBuffer> producer_buffer = queue_->GetBuffer(slot);
-    if (producer_buffer == nullptr || producer_buffer->buffer() == nullptr) {
-        ALOGE("detachBuffer: Invalid ProducerBuffer at slot %zu.", slot);
-        return BAD_VALUE;
-    }
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-    if (graphic_buffer == nullptr) {
-        ALOGE("detachBuffer: Invalid GraphicBuffer at slot %zu.", slot);
-        return BAD_VALUE;
-    }
-
-    // Remove the ProducerBuffer from the ProducerQueue.
-    status_t error = RemoveBuffer(slot);
-    if (error != NO_ERROR) {
-        ALOGE("detachBuffer: Failed to remove buffer, slot=%zu, error=%d.", slot, error);
-        return error;
-    }
-
-    // Here we need to convert the existing ProducerBuffer into a DetachedBufferHandle and inject
-    // the handle into the GraphicBuffer object at the requested slot.
-    auto status_or_handle = producer_buffer->Detach();
-    if (!status_or_handle.ok()) {
-        ALOGE("detachBuffer: Failed to detach from a ProducerBuffer at slot %zu, error=%d.", slot,
-              status_or_handle.error());
-        return BAD_VALUE;
-    }
-
-    // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
-    // be directly backed by BufferHub.
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) {
-    ALOGV("detachNextBuffer.");
-
-    if (out_buffer == nullptr || out_fence == nullptr) {
-        ALOGE("detachNextBuffer: Invalid parameter: out_buffer=%p, out_fence=%p", out_buffer,
-              out_fence);
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("detachNextBuffer: BufferHubProducer is not connected.");
-        return NO_INIT;
-    }
-
-    // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, and detachBuffer in
-    // sequence, except for two things:
-    //
-    // 1) It is unnecessary to know the dimensions, format, or usage of the next buffer, i.e. the
-    // function just returns whatever ProducerBuffer is available from the ProducerQueue and no
-    // buffer allocation or re-allocation will happen.
-    // 2) It will not block, since if it cannot find an appropriate buffer to return, it will return
-    // an error instead.
-    size_t slot = 0;
-    LocalHandle fence;
-
-    // First, dequeue a ProducerBuffer from the ProducerQueue with no timeout. Report error
-    // immediately if ProducerQueue::Dequeue() fails.
-    auto status_or_buffer = queue_->Dequeue(/*timeout=*/0, &slot, &fence);
-    if (!status_or_buffer.ok()) {
-        ALOGE("detachNextBuffer: Failed to dequeue buffer, error=%d.", status_or_buffer.error());
-        return NO_MEMORY;
-    }
-
-    std::shared_ptr<ProducerBuffer> producer_buffer = status_or_buffer.take();
-    if (producer_buffer == nullptr) {
-        ALOGE("detachNextBuffer: Dequeued buffer is null.");
-        return NO_MEMORY;
-    }
-
-    // With the BufferHub backed solution, slot returned from |queue_->Dequeue| is guaranteed to
-    // be available for producer's use. It's either in free state (if the buffer has never been used
-    // before) or in queued state (if the buffer has been dequeued and queued back to
-    // BufferHubQueue).
-    if (!buffers_[slot].mBufferState.isFree() && !buffers_[slot].mBufferState.isQueued()) {
-        ALOGE("detachNextBuffer: slot %zu is not free or queued, actual state: %s.", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    }
-    if (buffers_[slot].mProducerBuffer == nullptr) {
-        ALOGE("detachNextBuffer: ProducerBuffer at slot %zu is null.", slot);
-        return BAD_VALUE;
-    }
-    if (buffers_[slot].mProducerBuffer->id() != producer_buffer->id()) {
-        ALOGE("detachNextBuffer: ProducerBuffer at slot %zu has mismatched id, actual: "
-              "%d, expected: %d.",
-              slot, buffers_[slot].mProducerBuffer->id(), producer_buffer->id());
-        return BAD_VALUE;
-    }
-
-    ALOGV("detachNextBuffer: slot=%zu", slot);
-    buffers_[slot].mBufferState.freeQueued();
-    buffers_[slot].mBufferState.dequeue();
-
-    // Second, request the buffer.
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-    buffers_[slot].mGraphicBuffer = producer_buffer->buffer()->buffer();
-
-    // Finally, detach the buffer and then return.
-    status_t error = DetachBufferLocked(slot);
-    if (error == NO_ERROR) {
-        *out_fence = new Fence(fence.Release());
-        *out_buffer = graphic_buffer;
-    }
-    return error;
-}
-
-status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) {
-    // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only
-    // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer.
-    ALOGV("queueBuffer: buffer=%p", buffer.get());
-
-    if (out_slot == nullptr) {
-        ALOGE("attachBuffer: out_slot cannot be NULL.");
-        return BAD_VALUE;
-    }
-    if (buffer == nullptr) {
-        ALOGE("attachBuffer: invalid GraphicBuffer.");
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("attachBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    // Before attaching the buffer, caller is supposed to call
-    // IGraphicBufferProducer::setGenerationNumber to inform the
-    // BufferHubProducer the next generation number.
-    if (buffer->getGenerationNumber() != generation_number_) {
-        ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.",
-              buffer->getGenerationNumber(), generation_number_);
-        return BAD_VALUE;
-    }
-
-    // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
-    // be directly backed by BufferHub.
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
-                                        QueueBufferOutput* output) {
-    ALOGV("queueBuffer: slot %d", slot);
-
-    if (output == nullptr) {
-        return BAD_VALUE;
-    }
-
-    int64_t timestamp;
-    bool is_auto_timestamp;
-    android_dataspace dataspace;
-    Rect crop(Rect::EMPTY_RECT);
-    int scaling_mode;
-    uint32_t transform;
-    sp<Fence> fence;
-
-    input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform,
-                  &fence);
-
-    // Check input scaling mode is valid.
-    switch (scaling_mode) {
-        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
-        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
-            break;
-        default:
-            ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
-            return BAD_VALUE;
-    }
-
-    // Check input fence is valid.
-    if (fence == nullptr) {
-        ALOGE("queueBuffer: fence is NULL");
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("queueBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) {
-        ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
-              "mGraphicBuffer=%p)",
-              slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get());
-        return BAD_VALUE;
-    }
-
-    // Post the producer buffer with timestamp in the metadata.
-    const auto& producer_buffer = buffers_[slot].mProducerBuffer;
-
-    // Check input crop is not out of boundary of current buffer.
-    Rect buffer_rect(producer_buffer->width(), producer_buffer->height());
-    Rect cropped_rect(Rect::EMPTY_RECT);
-    crop.intersect(buffer_rect, &cropped_rect);
-    if (cropped_rect != crop) {
-        ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
-        return BAD_VALUE;
-    }
-
-    LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
-
-    DvrNativeBufferMetadata meta_data;
-    meta_data.timestamp = timestamp;
-    meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
-    meta_data.dataspace = int32_t(dataspace);
-    meta_data.crop_left = crop.left;
-    meta_data.crop_top = crop.top;
-    meta_data.crop_right = crop.right;
-    meta_data.crop_bottom = crop.bottom;
-    meta_data.scaling_mode = int32_t(scaling_mode);
-    meta_data.transform = int32_t(transform);
-
-    producer_buffer->PostAsync(&meta_data, fence_fd);
-    buffers_[slot].mBufferState.queue();
-
-    output->width = producer_buffer->width();
-    output->height = producer_buffer->height();
-    output->transformHint = 0; // default value, we don't use it yet.
-
-    // |numPendingBuffers| counts of the number of buffers that has been enqueued
-    // by the producer but not yet acquired by the consumer. Due to the nature
-    // of BufferHubQueue design, this is hard to trace from the producer's client
-    // side, but it's safe to assume it's zero.
-    output->numPendingBuffers = 0;
-
-    // Note that we are not setting nextFrameNumber here as it seems to be only
-    // used by surface flinger. See more at b/22802885, ag/791760.
-    output->nextFrameNumber = 0;
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("cancelBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (fence == nullptr) {
-        ALOGE("cancelBuffer: fence is NULL");
-        return BAD_VALUE;
-    }
-
-    auto producer_buffer = buffers_[slot].mProducerBuffer;
-    queue_->Enqueue(producer_buffer, size_t(slot), 0U);
-    buffers_[slot].mBufferState.cancel();
-    buffers_[slot].mFence = fence;
-    ALOGV("cancelBuffer: slot %d", slot);
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::query(int what, int* out_value) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (out_value == nullptr) {
-        ALOGE("query: out_value was NULL");
-        return BAD_VALUE;
-    }
-
-    int value = 0;
-    switch (what) {
-        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
-            // TODO(b/36187402) This should be the maximum number of buffers that this
-            // producer queue's consumer can acquire. Set to be at least one. Need to
-            // find a way to set from the consumer side.
-            value = kDefaultUndequeuedBuffers;
-            break;
-        case NATIVE_WINDOW_BUFFER_AGE:
-            value = 0;
-            break;
-        case NATIVE_WINDOW_WIDTH:
-            value = int32_t(queue_->default_width());
-            break;
-        case NATIVE_WINDOW_HEIGHT:
-            value = int32_t(queue_->default_height());
-            break;
-        case NATIVE_WINDOW_FORMAT:
-            value = int32_t(queue_->default_format());
-            break;
-        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
-            // BufferHubQueue is always operating in async mode, thus semantically
-            // consumer can never be running behind. See BufferQueueCore.cpp core
-            // for more information about the original meaning of this flag.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
-            // TODO(jwcai) This is currently not implement as we don't need
-            // IGraphicBufferConsumer parity.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_DEFAULT_DATASPACE:
-            // TODO(jwcai) Return the default value android::BufferQueue is using as
-            // there is no way dvr::ConsumerQueue can set it.
-            value = 0; // HAL_DATASPACE_UNKNOWN
-            break;
-        case NATIVE_WINDOW_STICKY_TRANSFORM:
-            // TODO(jwcai) Return the default value android::BufferQueue is using as
-            // there is no way dvr::ConsumerQueue can set it.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
-            // In Daydream's implementation, the consumer end (i.e. VR Compostior)
-            // knows how to handle protected buffers.
-            value = 1;
-            break;
-        default:
-            return BAD_VALUE;
-    }
-
-    ALOGV("query: key=%d, v=%d", what, value);
-    *out_value = value;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api,
-                                    bool /* producer_controlled_by_app */,
-                                    QueueBufferOutput* output) {
-    // Consumer interaction are actually handled by buffer hub, and we need
-    // to maintain consumer operations here. We only need to perform basic input
-    // parameter checks here.
-    ALOGV(__FUNCTION__);
-
-    if (output == nullptr) {
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ != kNoConnectedApi) {
-        return BAD_VALUE;
-    }
-
-    if (!queue_->is_connected()) {
-        ALOGE("BufferHubProducer::connect: This BufferHubProducer is not "
-              "connected to bufferhud. Has it been taken out as a parcelable?");
-        return BAD_VALUE;
-    }
-
-    switch (api) {
-        case NATIVE_WINDOW_API_EGL:
-        case NATIVE_WINDOW_API_CPU:
-        case NATIVE_WINDOW_API_MEDIA:
-        case NATIVE_WINDOW_API_CAMERA:
-            connected_api_ = api;
-
-            output->width = queue_->default_width();
-            output->height = queue_->default_height();
-
-            // default values, we don't use them yet.
-            output->transformHint = 0;
-            output->numPendingBuffers = 0;
-            output->nextFrameNumber = 0;
-            output->bufferReplaced = false;
-
-            break;
-        default:
-            ALOGE("BufferHubProducer::connect: unknow API %d", api);
-            return BAD_VALUE;
-    }
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
-    // Consumer interaction are actually handled by buffer hub, and we need
-    // to maintain consumer operations here.  We only need to perform basic input
-    // parameter checks here.
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (kNoConnectedApi == connected_api_) {
-        return NO_INIT;
-    } else if (api != connected_api_) {
-        return BAD_VALUE;
-    }
-
-    FreeAllBuffers();
-    connected_api_ = kNoConnectedApi;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
-    if (stream != nullptr) {
-        // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
-        // metadata.
-        ALOGE("SidebandStream is not currently supported.");
-        return INVALID_OPERATION;
-    }
-    return NO_ERROR;
-}
-
-void BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */,
-                                        PixelFormat /* format */, uint64_t /* usage */) {
-    // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
-    // of buffers permitted by the current BufferQueue configuration (aka
-    // |max_buffer_count_|).
-    ALOGE("BufferHubProducer::allocateBuffers not implemented.");
-}
-
-status_t BufferHubProducer::allowAllocation(bool /* allow */) {
-    ALOGE("BufferHubProducer::allowAllocation not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-    generation_number_ = generation_number;
-    return NO_ERROR;
-}
-
-String8 BufferHubProducer::getConsumerName() const {
-    // BufferHub based implementation could have one to many producer/consumer
-    // relationship, thus |getConsumerName| from the producer side does not
-    // make any sense.
-    ALOGE("BufferHubProducer::getConsumerName not supported.");
-    return String8("BufferHubQueue::StubConsumer");
-}
-
-status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
-    if (shared_buffer_mode) {
-        ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
-        // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
-        return INVALID_OPERATION;
-    }
-    // Setting to default should just work as a no-op.
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
-    if (auto_refresh) {
-        ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
-        return INVALID_OPERATION;
-    }
-    // Setting to default should just work as a no-op.
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-    dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */,
-                                                sp<Fence>* /* out_fence */,
-                                                float /*out_transform_matrix*/[16]) {
-    ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
-    return INVALID_OPERATION;
-}
-
-void BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {
-    ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
-}
-
-status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
-    ALOGV(__FUNCTION__);
-
-    *out_id = unique_id_;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
-    ALOGV(__FUNCTION__);
-
-    // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
-    *out_usage = 0;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) {
-    if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE;
-
-    if (connected_api_ != kNoConnectedApi) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
-              "connected client. Must disconnect first.");
-        return BAD_VALUE;
-    }
-
-    if (!queue_->is_connected()) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
-              "is not connected to bufferhud. Has it been taken out as a "
-              "parcelable?");
-        return BAD_VALUE;
-    }
-
-    auto status = queue_->TakeAsParcelable();
-    if (!status) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out "
-              "ProducuerQueueParcelable from the producer queue, error: %s.",
-              status.GetErrorMessage().c_str());
-        return BAD_VALUE;
-    }
-
-    *out_parcelable = status.take();
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
-                                           PixelFormat format, uint64_t usage) {
-    auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage);
-    if (!status) {
-        ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
-              status.GetErrorMessage().c_str());
-        return NO_MEMORY;
-    }
-
-    size_t slot = status.get();
-    auto producer_buffer = queue_->GetBuffer(slot);
-
-    LOG_ALWAYS_FATAL_IF(producer_buffer == nullptr,
-                        "Failed to get the producer buffer at slot: %zu", slot);
-
-    buffers_[slot].mProducerBuffer = producer_buffer;
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::RemoveBuffer(size_t slot) {
-    auto status = queue_->RemoveBuffer(slot);
-    if (!status) {
-        ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer at slot: %zu, error: %s.",
-              slot, status.GetErrorMessage().c_str());
-        return INVALID_OPERATION;
-    }
-
-    // Reset in memory objects related the the buffer.
-    buffers_[slot].mProducerBuffer = nullptr;
-    buffers_[slot].mBufferState.detachProducer();
-    buffers_[slot].mFence = Fence::NO_FENCE;
-    buffers_[slot].mGraphicBuffer = nullptr;
-    buffers_[slot].mRequestBufferCalled = false;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::FreeAllBuffers() {
-    for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
-        // Reset in memory objects related the the buffer.
-        buffers_[slot].mProducerBuffer = nullptr;
-        buffers_[slot].mBufferState.reset();
-        buffers_[slot].mFence = Fence::NO_FENCE;
-        buffers_[slot].mGraphicBuffer = nullptr;
-        buffers_[slot].mRequestBufferCalled = false;
-    }
-
-    auto status = queue_->FreeAllBuffers();
-    if (!status) {
-        ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
-              "the queue: %s",
-              status.GetErrorMessage().c_str());
-    }
-
-    if (queue_->capacity() != 0 || queue_->count() != 0) {
-        LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
-    }
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::exportToParcel(Parcel* parcel) {
-    status_t res = TakeAsParcelable(&pending_producer_parcelable_);
-    if (res != NO_ERROR) return res;
-
-    if (!pending_producer_parcelable_.IsValid()) {
-        ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object.");
-        return BAD_VALUE;
-    }
-
-    res = parcel->writeUint32(USE_BUFFER_HUB);
-    if (res != NO_ERROR) {
-        ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res);
-        return res;
-    }
-
-    return pending_producer_parcelable_.writeToParcel(parcel);
-}
-
-IBinder* BufferHubProducer::onAsBinder() {
-    ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder "
-          "object.");
-    return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c1d92a2..66cad03 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -18,11 +18,6 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubConsumer.h>
-#include <gui/BufferHubProducer.h>
-#endif
-
 #include <gui/BufferQueue.h>
 #include <gui/BufferQueueConsumer.h>
 #include <gui/BufferQueueCore.h>
@@ -127,32 +122,4 @@
     *outConsumer = consumer;
 }
 
-#ifndef NO_BUFFERHUB
-void BufferQueue::createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
-                                       sp<IGraphicBufferConsumer>* outConsumer) {
-    LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL");
-    LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL");
-
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-
-    dvr::ProducerQueueConfigBuilder configBuilder;
-    std::shared_ptr<dvr::ProducerQueue> producerQueue =
-            dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{});
-    LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue.");
-
-    std::shared_ptr<dvr::ConsumerQueue> consumerQueue = producerQueue->CreateConsumerQueue();
-    LOG_ALWAYS_FATAL_IF(consumerQueue == nullptr, "BufferQueue: failed to create ConsumerQueue.");
-
-    producer = BufferHubProducer::Create(producerQueue);
-    consumer = BufferHubConsumer::Create(consumerQueue);
-
-    LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer");
-    LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer");
-
-    *outProducer = producer;
-    *outConsumer = consumer;
-}
-#endif
-
 }; // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 797069c..918ff2d 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -27,10 +27,6 @@
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
 
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubProducer.h>
-#endif
-
 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
 #include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
 #include <gui/BufferQueueDefs.h>
@@ -1012,17 +1008,7 @@
         }
         case USE_BUFFER_HUB: {
             ALOGE("createFromParcel: BufferHub not implemented.");
-#ifndef NO_BUFFERHUB
-            dvr::ProducerQueueParcelable producerParcelable;
-            res = producerParcelable.readFromParcel(parcel);
-            if (res != NO_ERROR) {
-                ALOGE("createFromParcel: Failed to read from parcel, error=%d", res);
-                return nullptr;
-            }
-            return BufferHubProducer::Create(std::move(producerParcelable));
-#else
             return nullptr;
-#endif
         }
         default: {
             ALOGE("createFromParcel: Unexpected mgaic: 0x%x.", outMagic);
diff --git a/libs/gui/include/gui/BufferHubConsumer.h b/libs/gui/include/gui/BufferHubConsumer.h
deleted file mode 100644
index d380770..0000000
--- a/libs/gui/include/gui/BufferHubConsumer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 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_GUI_BUFFERHUBCONSUMER_H_
-#define ANDROID_GUI_BUFFERHUBCONSUMER_H_
-
-#include <gui/IGraphicBufferConsumer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubConsumer : public IGraphicBufferConsumer {
-public:
-    // Creates a BufferHubConsumer instance by importing an existing producer queue.
-    static sp<BufferHubConsumer> Create(const std::shared_ptr<dvr::ConsumerQueue>& queue);
-
-    // Creates a BufferHubConsumer instance by importing an existing producer
-    // parcelable. Note that this call takes the ownership of the parcelable
-    // object and is guaranteed to succeed if parcelable object is valid.
-    static sp<BufferHubConsumer> Create(dvr::ConsumerQueueParcelable parcelable);
-
-    // See |IGraphicBufferConsumer::acquireBuffer|
-    status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen,
-                           uint64_t maxFrameNumber = 0) override;
-
-    // See |IGraphicBufferConsumer::detachBuffer|
-    status_t detachBuffer(int slot) override;
-
-    // See |IGraphicBufferConsumer::attachBuffer|
-    status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override;
-
-    // See |IGraphicBufferConsumer::releaseBuffer|
-    status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence,
-                           const sp<Fence>& releaseFence) override;
-
-    // See |IGraphicBufferConsumer::consumerConnect|
-    status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override;
-
-    // See |IGraphicBufferConsumer::consumerDisconnect|
-    status_t consumerDisconnect() override;
-
-    // See |IGraphicBufferConsumer::getReleasedBuffers|
-    status_t getReleasedBuffers(uint64_t* slotMask) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferSize|
-    status_t setDefaultBufferSize(uint32_t w, uint32_t h) override;
-
-    // See |IGraphicBufferConsumer::setMaxBufferCount|
-    status_t setMaxBufferCount(int bufferCount) override;
-
-    // See |IGraphicBufferConsumer::setMaxAcquiredBufferCount|
-    status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override;
-
-    // See |IGraphicBufferConsumer::setConsumerName|
-    status_t setConsumerName(const String8& name) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferFormat|
-    status_t setDefaultBufferFormat(PixelFormat defaultFormat) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferDataSpace|
-    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override;
-
-    // See |IGraphicBufferConsumer::setConsumerUsageBits|
-    status_t setConsumerUsageBits(uint64_t usage) override;
-
-    // See |IGraphicBufferConsumer::setConsumerIsProtected|
-    status_t setConsumerIsProtected(bool isProtected) override;
-
-    // See |IGraphicBufferConsumer::setTransformHint|
-    status_t setTransformHint(uint32_t hint) override;
-
-    // See |IGraphicBufferConsumer::getSidebandStream|
-    status_t getSidebandStream(sp<NativeHandle>* outStream) const override;
-
-    // See |IGraphicBufferConsumer::getOccupancyHistory|
-    status_t getOccupancyHistory(bool forceFlush,
-                                 std::vector<OccupancyTracker::Segment>* outHistory) override;
-
-    // See |IGraphicBufferConsumer::discardFreeBuffers|
-    status_t discardFreeBuffers() override;
-
-    // See |IGraphicBufferConsumer::dumpState|
-    status_t dumpState(const String8& prefix, String8* outResult) const override;
-
-    // BufferHubConsumer provides its own logic to cast to a binder object.
-    IBinder* onAsBinder() override;
-
-private:
-    // Private constructor to force use of |Create|.
-    BufferHubConsumer() = default;
-
-    // Concrete implementation backed by BufferHubBuffer.
-    std::shared_ptr<dvr::ConsumerQueue> mQueue;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBCONSUMER_H_
diff --git a/libs/gui/include/gui/BufferHubProducer.h b/libs/gui/include/gui/BufferHubProducer.h
deleted file mode 100644
index 0e925ce..0000000
--- a/libs/gui/include/gui/BufferHubProducer.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 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_GUI_BUFFERHUBPRODUCER_H_
-#define ANDROID_GUI_BUFFERHUBPRODUCER_H_
-
-#include <gui/BufferSlot.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubProducer : public IGraphicBufferProducer {
-public:
-    static constexpr int kNoConnectedApi = -1;
-
-    // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer
-    // side logic doesn't limit the number of buffer it can acquire
-    // simultaneously. We need a way for consumer logic to configure and enforce
-    // that.
-    static constexpr int kDefaultUndequeuedBuffers = 1;
-
-    // Creates a BufferHubProducer instance by importing an existing prodcuer
-    // queue.
-    static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer);
-
-    // Creates a BufferHubProducer instance by importing an existing prodcuer
-    // parcelable. Note that this call takes the ownership of the parcelable
-    // object and is guaranteed to succeed if parcelable object is valid.
-    static sp<BufferHubProducer> Create(dvr::ProducerQueueParcelable parcelable);
-
-    // See |IGraphicBufferProducer::requestBuffer|
-    status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
-
-    // For the BufferHub based implementation. All buffers in the queue are
-    // allowed to be dequeued from the consumer side. It call always returns
-    // 0 for |NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS| query. Thus setting
-    // |max_dequeued_buffers| here can be considered the same as setting queue
-    // capacity.
-    //
-    // See |IGraphicBufferProducer::setMaxDequeuedBufferCount| for more info
-    status_t setMaxDequeuedBufferCount(int max_dequeued_buffers) override;
-
-    // See |IGraphicBufferProducer::setAsyncMode|
-    status_t setAsyncMode(bool async) override;
-
-    // See |IGraphicBufferProducer::dequeueBuffer|
-    status_t dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
-                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
-                           FrameEventHistoryDelta* outTimestamps) override;
-
-    // See |IGraphicBufferProducer::detachBuffer|
-    status_t detachBuffer(int slot) override;
-
-    // See |IGraphicBufferProducer::detachNextBuffer|
-    status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override;
-
-    // See |IGraphicBufferProducer::attachBuffer|
-    status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override;
-
-    // See |IGraphicBufferProducer::queueBuffer|
-    status_t queueBuffer(int slot, const QueueBufferInput& input,
-                         QueueBufferOutput* output) override;
-
-    // See |IGraphicBufferProducer::cancelBuffer|
-    status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
-
-    // See |IGraphicBufferProducer::query|
-    status_t query(int what, int* out_value) override;
-
-    // See |IGraphicBufferProducer::connect|
-    status_t connect(const sp<IProducerListener>& listener, int api,
-                     bool producer_controlled_by_app, QueueBufferOutput* output) override;
-
-    // See |IGraphicBufferProducer::disconnect|
-    status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override;
-
-    // See |IGraphicBufferProducer::setSidebandStream|
-    status_t setSidebandStream(const sp<NativeHandle>& stream) override;
-
-    // See |IGraphicBufferProducer::allocateBuffers|
-    void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format,
-                         uint64_t usage) override;
-
-    // See |IGraphicBufferProducer::allowAllocation|
-    status_t allowAllocation(bool allow) override;
-
-    // See |IGraphicBufferProducer::setGenerationNumber|
-    status_t setGenerationNumber(uint32_t generation_number) override;
-
-    // See |IGraphicBufferProducer::getConsumerName|
-    String8 getConsumerName() const override;
-
-    // See |IGraphicBufferProducer::setSharedBufferMode|
-    status_t setSharedBufferMode(bool shared_buffer_mode) override;
-
-    // See |IGraphicBufferProducer::setAutoRefresh|
-    status_t setAutoRefresh(bool auto_refresh) override;
-
-    // See |IGraphicBufferProducer::setDequeueTimeout|
-    status_t setDequeueTimeout(nsecs_t timeout) override;
-
-    // See |IGraphicBufferProducer::getLastQueuedBuffer|
-    status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence,
-                                 float out_transform_matrix[16]) override;
-
-    // See |IGraphicBufferProducer::getFrameTimestamps|
-    void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override;
-
-    // See |IGraphicBufferProducer::getUniqueId|
-    status_t getUniqueId(uint64_t* out_id) const override;
-
-    // See |IGraphicBufferProducer::getConsumerUsage|
-    status_t getConsumerUsage(uint64_t* out_usage) const override;
-
-    // Takes out the current producer as a binder parcelable object. Note that the
-    // producer must be disconnected to be exportable. After successful export,
-    // the producer queue can no longer be connected again. Returns NO_ERROR when
-    // takeout is successful and out_parcelable will hold the new parcelable
-    // object. Also note that out_parcelable cannot be NULL and must points to an
-    // invalid parcelable.
-    status_t TakeAsParcelable(dvr::ProducerQueueParcelable* out_parcelable);
-
-    IBinder* onAsBinder() override;
-
-protected:
-    // See |IGraphicBufferProducer::exportToParcel|
-    status_t exportToParcel(Parcel* parcel) override;
-
-private:
-    using LocalHandle = pdx::LocalHandle;
-
-    // Private constructor to force use of |Create|.
-    BufferHubProducer() {}
-
-    static uint64_t genUniqueId() {
-        static std::atomic<uint32_t> counter{0};
-        static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
-        return id | counter++;
-    }
-
-    // Allocate new buffer through BufferHub and add it into |queue_| for
-    // bookkeeping.
-    status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
-                            PixelFormat format, uint64_t usage);
-
-    // Remove a buffer via BufferHubRPC.
-    status_t RemoveBuffer(size_t slot);
-
-    // Free all buffers which are owned by the prodcuer. Note that if graphic
-    // buffers are acquired by the consumer, we can't .
-    status_t FreeAllBuffers();
-
-    // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been
-    // locked already.
-    status_t DetachBufferLocked(size_t slot);
-
-    // Concreate implementation backed by BufferHubBuffer.
-    std::shared_ptr<dvr::ProducerQueue> queue_;
-
-    // Mutex for thread safety.
-    std::mutex mutex_;
-
-    // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
-    int connected_api_{kNoConnectedApi};
-
-    // |max_buffer_count_| sets the capacity of the underlying buffer queue.
-    int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
-
-    // |max_dequeued_buffer_count_| set the maximum number of buffers that can
-    // be dequeued at the same momment.
-    int32_t max_dequeued_buffer_count_{1};
-
-    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
-    // slot is not yet available. The timeout is stored in milliseconds.
-    int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut};
-
-    // |generation_number_| stores the current generation number of the attached
-    // producer. Any attempt to attach a buffer with a different generation
-    // number will fail.
-    // TOOD(b/38137191) Currently not used as we don't support
-    // IGraphicBufferProducer::detachBuffer.
-    uint32_t generation_number_{0};
-
-    // |buffers_| stores the buffers that have been dequeued from
-    // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
-    // filled in with the result of |Dequeue|.
-    // TODO(jwcai) The buffer allocated to a slot will also be replaced if the
-    // requested buffer usage or geometry differs from that of the buffer
-    // allocated to a slot.
-    struct BufferHubSlot : public BufferSlot {
-        BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
-        // BufferSlot comes from android framework, using m prefix to comply with
-        // the name convention with the reset of data fields from BufferSlot.
-        std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
-        bool mIsReallocating;
-    };
-    BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
-
-    // A uniqueId used by IGraphicBufferProducer interface.
-    const uint64_t unique_id_{genUniqueId()};
-
-    // A pending parcelable object which keeps the bufferhub channel alive.
-    dvr::ProducerQueueParcelable pending_producer_parcelable_;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index 91f80d2..690587f 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -82,12 +82,6 @@
             sp<IGraphicBufferConsumer>* outConsumer,
             bool consumerIsSurfaceFlinger = false);
 
-#ifndef NO_BUFFERHUB
-    // Creates an IGraphicBufferProducer and IGraphicBufferConsumer pair backed by BufferHub.
-    static void createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
-                                     sp<IGraphicBufferConsumer>* outConsumer);
-#endif
-
     BufferQueue() = delete; // Create through createBufferQueue
 };
 
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index fc68ad2..fa54c7d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -92,39 +92,6 @@
     header_libs: ["libsurfaceflinger_headers"],
 }
 
-// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-// This test has a main method, and requires a separate binary to be built.
-// To add move tests like this, just add additional cc_test statements,
-// as opposed to adding more source files to this one.
-cc_test {
-    name: "SurfaceParcelable_test",
-    test_suites: ["device-tests"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    srcs: [
-        "SurfaceParcelable_test.cpp",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libbinder",
-        "libcutils",
-        "libgui",
-        "libui",
-        "libutils",
-        "libbufferhubqueue", // TODO(b/70046255): Remove these once BufferHub is integrated into libgui.
-        "libpdx_default_transport",
-    ],
-
-    header_libs: [
-        "libdvr_headers",
-    ],
-}
-
 cc_test {
     name: "SamplingDemo",
 
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 2af2fe1..3427731 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -42,10 +42,6 @@
 #define TEST_CONTROLLED_BY_APP false
 #define TEST_PRODUCER_USAGE_BITS (0)
 
-#ifndef USE_BUFFER_HUB_AS_BUFFER_QUEUE
-#define USE_BUFFER_HUB_AS_BUFFER_QUEUE 0
-#endif
-
 namespace android {
 
 namespace {
@@ -77,7 +73,6 @@
     // Enums to control which IGraphicBufferProducer backend to test.
     enum IGraphicBufferProducerTestCode {
         USE_BUFFER_QUEUE_PRODUCER = 0,
-        USE_BUFFER_HUB_PRODUCER,
     };
 }; // namespace anonymous
 
@@ -99,10 +94,6 @@
                 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
                 break;
             }
-            case USE_BUFFER_HUB_PRODUCER: {
-                BufferQueue::createBufferHubQueue(&mProducer, &mConsumer);
-                break;
-            }
             default: {
                 // Should never reach here.
                 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
@@ -880,11 +871,6 @@
 }
 
 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
-    if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
-        // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true)
-        return;
-    }
-
     ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
     ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
@@ -1117,14 +1103,7 @@
     }
 }
 
-#if USE_BUFFER_HUB_AS_BUFFER_QUEUE
-INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
-                        ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER));
-#else
-// TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can
-// pass all existing libgui tests.
 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
-#endif
 
 } // namespace android
diff --git a/libs/gui/tests/SurfaceParcelable_test.cpp b/libs/gui/tests/SurfaceParcelable_test.cpp
deleted file mode 100644
index 686dc82..0000000
--- a/libs/gui/tests/SurfaceParcelable_test.cpp
+++ /dev/null
@@ -1,168 +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 "SurfaceParcelable_test"
-
-#include <gtest/gtest.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/BufferQueue.h>
-#include <gui/view/Surface.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static const String16 kTestServiceName = String16("SurfaceParcelableTestService");
-static const String16 kSurfaceName = String16("TEST_SURFACE");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-
-enum SurfaceParcelableTestServiceCode {
-    CREATE_BUFFER_QUEUE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_BUFFER_HUB_SURFACE,
-};
-
-class SurfaceParcelableTestService : public BBinder {
-public:
-    SurfaceParcelableTestService() {
-        // BufferQueue
-        BufferQueue::createBufferQueue(&mBufferQueueProducer, &mBufferQueueConsumer);
-
-        // BufferHub
-        dvr::ProducerQueueConfigBuilder configBuilder;
-        mProducerQueue = dvr::ProducerQueue::Create(configBuilder.SetDefaultWidth(kBufferWidth)
-                                                            .SetDefaultHeight(kBufferHeight)
-                                                            .SetDefaultFormat(kBufferFormat)
-                                                            .Build(),
-                                                    dvr::UsagePolicy{});
-        mBufferHubProducer = BufferHubProducer::Create(mProducerQueue);
-    }
-
-    ~SurfaceParcelableTestService() = default;
-
-    virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply,
-                                uint32_t /*flags*/ = 0) {
-        switch (code) {
-            case CREATE_BUFFER_QUEUE_SURFACE: {
-                view::Surface surfaceShim;
-                surfaceShim.name = kSurfaceName;
-                surfaceShim.graphicBufferProducer = mBufferQueueProducer;
-                return surfaceShim.writeToParcel(reply);
-            }
-            case CREATE_BUFFER_HUB_SURFACE: {
-                view::Surface surfaceShim;
-                surfaceShim.name = kSurfaceName;
-                surfaceShim.graphicBufferProducer = mBufferHubProducer;
-                return surfaceShim.writeToParcel(reply);
-            }
-            default:
-                return UNKNOWN_TRANSACTION;
-        };
-    }
-
-protected:
-    sp<IGraphicBufferProducer> mBufferQueueProducer;
-    sp<IGraphicBufferConsumer> mBufferQueueConsumer;
-
-    std::shared_ptr<dvr::ProducerQueue> mProducerQueue;
-    sp<IGraphicBufferProducer> mBufferHubProducer;
-};
-
-static int runBinderServer() {
-    ProcessState::self()->startThreadPool();
-
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService;
-    sm->addService(kTestServiceName, service, false);
-
-    ALOGI("Binder server running...");
-
-    while (true) {
-        int stat, retval;
-        retval = wait(&stat);
-        if (retval == -1 && errno == ECHILD) {
-            break;
-        }
-    }
-
-    ALOGI("Binder server exiting...");
-    return 0;
-}
-
-class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> {
-protected:
-    virtual void SetUp() {
-        mService = defaultServiceManager()->getService(kTestServiceName);
-        if (mService == nullptr) {
-            ALOGE("Failed to connect to the test service.");
-            return;
-        }
-
-        ALOGI("Binder service is ready for client.");
-    }
-
-    status_t GetSurface(view::Surface* surfaceShim) {
-        ALOGI("...Test: %d", GetParam());
-
-        uint32_t opCode = GetParam();
-        Parcel data;
-        Parcel reply;
-        status_t error = mService->transact(opCode, data, &reply);
-        if (error != NO_ERROR) {
-            ALOGE("Failed to get surface over binder, error=%d.", error);
-            return error;
-        }
-
-        error = surfaceShim->readFromParcel(&reply);
-        if (error != NO_ERROR) {
-            ALOGE("Failed to get surface from parcel, error=%d.", error);
-            return error;
-        }
-
-        return NO_ERROR;
-    }
-
-private:
-    sp<IBinder> mService;
-};
-
-TEST_P(SurfaceParcelableTest, SendOverBinder) {
-    view::Surface surfaceShim;
-    EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR);
-    EXPECT_EQ(surfaceShim.name, kSurfaceName);
-    EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr);
-}
-
-INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest,
-                        ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE));
-
-} // namespace android
-
-int main(int argc, char** argv) {
-    pid_t pid = fork();
-    if (pid == 0) {
-        android::ProcessState::self()->startThreadPool();
-        ::testing::InitGoogleTest(&argc, argv);
-        return RUN_ALL_TESTS();
-
-    } else {
-        ALOGI("Test process pid: %d.", pid);
-        return android::runBinderServer();
-    }
-}
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
deleted file mode 100644
index e33e03b..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_native_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_benchmark {
-    srcs: ["buffer_transport_benchmark.cpp"],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "libdvr.google",
-        "libgui",
-        "liblog",
-        "libhardware",
-        "libui",
-        "libutils",
-        "libnativewindow",
-        "libbufferhubqueue",
-        "libpdx_default_transport",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"buffer_transport_benchmark\"",
-        "-DTRACE=0",
-        "-O2",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "buffer_transport_benchmark",
-}
diff --git a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
deleted file mode 100644
index b6813eb..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-#include <android-base/logging.h>
-#include <android/native_window.h>
-#include <benchmark/benchmark.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <dvr/dvr_api.h>
-#include <gui/BufferItem.h>
-#include <gui/BufferItemConsumer.h>
-#include <gui/Surface.h>
-#include <private/dvr/epoll_file_descriptor.h>
-#include <utils/Trace.h>
-
-#include <chrono>
-#include <functional>
-#include <iostream>
-#include <thread>
-#include <vector>
-
-#include <dlfcn.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/wait.h>
-
-// Use ALWAYS at the tag level. Control is performed manually during command
-// line processing.
-#ifdef ATRACE_TAG
-#undef ATRACE_TAG
-#endif
-#define ATRACE_TAG ATRACE_TAG_ALWAYS
-
-using namespace android;
-using ::benchmark::State;
-
-static const String16 kBinderService = String16("bufferTransport");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-static const uint64_t kBufferUsage =
-    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-static const uint32_t kBufferLayer = 1;
-static const int kMaxAcquiredImages = 1;
-static const int kQueueDepth = 2;  // We are double buffering for this test.
-static const size_t kMaxQueueCounts = 128;
-static const int kInvalidFence = -1;
-
-enum BufferTransportServiceCode {
-  CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-// A binder services that minics a compositor that consumes buffers. It provides
-// one Binder interface to create a new Surface for buffer producer to write
-// into; while itself will carry out no-op buffer consuming by acquiring then
-// releasing the buffer immediately.
-class BufferTransportService : public BBinder {
- public:
-  BufferTransportService() = default;
-  ~BufferTransportService() = default;
-
-  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                              uint32_t flags = 0) {
-    (void)flags;
-    (void)data;
-    switch (code) {
-      case CREATE_BUFFER_QUEUE: {
-        auto new_queue = std::make_shared<BufferQueueHolder>(this);
-        reply->writeStrongBinder(
-            IGraphicBufferProducer::asBinder(new_queue->producer));
-        buffer_queues_.push_back(new_queue);
-        return OK;
-      }
-      default:
-        return UNKNOWN_TRANSACTION;
-    };
-  }
-
- private:
-  struct FrameListener : public ConsumerBase::FrameAvailableListener {
-   public:
-    FrameListener(BufferTransportService* /*service*/,
-                  sp<BufferItemConsumer> buffer_item_consumer)
-        : buffer_item_consumer_(buffer_item_consumer) {}
-
-    void onFrameAvailable(const BufferItem& /*item*/) override {
-      BufferItem buffer;
-      status_t ret = 0;
-      {
-        ATRACE_NAME("AcquireBuffer");
-        ret = buffer_item_consumer_->acquireBuffer(&buffer, /*presentWhen=*/0,
-                                                   /*waitForFence=*/false);
-      }
-
-      if (ret != OK) {
-        LOG(ERROR) << "Failed to acquire next buffer.";
-        return;
-      }
-
-      {
-        ATRACE_NAME("ReleaseBuffer");
-        ret = buffer_item_consumer_->releaseBuffer(buffer);
-      }
-
-      if (ret != OK) {
-        LOG(ERROR) << "Failed to release buffer.";
-        return;
-      }
-    }
-
-   private:
-    sp<BufferItemConsumer> buffer_item_consumer_;
-  };
-
-  struct BufferQueueHolder {
-    explicit BufferQueueHolder(BufferTransportService* service) {
-      BufferQueue::createBufferQueue(&producer, &consumer);
-
-      sp<BufferItemConsumer> buffer_item_consumer =
-          new BufferItemConsumer(consumer, kBufferUsage, kMaxAcquiredImages,
-                                 /*controlledByApp=*/true);
-      buffer_item_consumer->setName(String8("BinderBufferTransport"));
-      frame_listener_ = new FrameListener(service, buffer_item_consumer);
-      buffer_item_consumer->setFrameAvailableListener(frame_listener_);
-    }
-
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-
-   private:
-    sp<FrameListener> frame_listener_;
-  };
-
-  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-// A virtual interfaces that abstracts the common BufferQueue operations, so
-// that the test suite can use the same test case to drive different types of
-// transport backends.
-class BufferTransport {
- public:
-  virtual ~BufferTransport() {}
-
-  virtual int Start() = 0;
-  virtual sp<Surface> CreateSurface() = 0;
-};
-
-// Binder-based buffer transport backend.
-//
-// On Start() a new process will be swapned to run a Binder server that
-// actually consumes the buffer.
-// On CreateSurface() a new Binder BufferQueue will be created, which the
-// service holds the concrete binder node of the IGraphicBufferProducer while
-// sending the binder proxy to the client. In another word, the producer side
-// operations are carried out process while the consumer side operations are
-// carried out within the BufferTransportService's own process.
-class BinderBufferTransport : public BufferTransport {
- public:
-  BinderBufferTransport() {}
-
-  int Start() override {
-    sp<IServiceManager> sm = defaultServiceManager();
-    service_ = sm->getService(kBinderService);
-    if (service_ == nullptr) {
-      LOG(ERROR) << "Failed to get the benchmark service.";
-      return -EIO;
-    }
-
-    LOG(INFO) << "Binder server is ready for client.";
-    return 0;
-  }
-
-  sp<Surface> CreateSurface() override {
-    Parcel data;
-    Parcel reply;
-    int error = service_->transact(CREATE_BUFFER_QUEUE, data, &reply);
-    if (error != OK) {
-      LOG(ERROR) << "Failed to get buffer queue over binder.";
-      return nullptr;
-    }
-
-    sp<IBinder> binder;
-    error = reply.readNullableStrongBinder(&binder);
-    if (error != OK) {
-      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
-      return nullptr;
-    }
-
-    auto producer = interface_cast<IGraphicBufferProducer>(binder);
-    if (producer == nullptr) {
-      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
-      return nullptr;
-    }
-
-    sp<Surface> surface = new Surface(producer, /*controlledByApp=*/true);
-
-    // Set buffer dimension.
-    ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
-    ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight,
-                                     kBufferFormat);
-
-    return surface;
-  }
-
- private:
-  sp<IBinder> service_;
-};
-
-class DvrApi {
- public:
-  DvrApi() {
-    handle_ = dlopen("libdvr.google.so", RTLD_NOW | RTLD_LOCAL);
-    CHECK(handle_);
-
-    auto dvr_get_api =
-        reinterpret_cast<decltype(&dvrGetApi)>(dlsym(handle_, "dvrGetApi"));
-    int ret = dvr_get_api(&api_, sizeof(api_), /*version=*/1);
-
-    CHECK(ret == 0);
-  }
-
-  ~DvrApi() { dlclose(handle_); }
-
-  const DvrApi_v1& Api() { return api_; }
-
- private:
-  void* handle_ = nullptr;
-  DvrApi_v1 api_;
-};
-
-// BufferHub/PDX-based buffer transport.
-//
-// On Start() a new thread will be swapned to run an epoll polling thread which
-// minics the behavior of a compositor. Similar to Binder-based backend, the
-// buffer available handler is also a no-op: Buffer gets acquired and released
-// immediately.
-// On CreateSurface() a pair of dvr::ProducerQueue and dvr::ConsumerQueue will
-// be created. The epoll thread holds on the consumer queue and dequeues buffer
-// from it; while the producer queue will be wrapped in a Surface and returned
-// to test suite.
-class BufferHubTransport : public BufferTransport {
- public:
-  virtual ~BufferHubTransport() {
-    stopped_.store(true);
-    if (reader_thread_.joinable()) {
-      reader_thread_.join();
-    }
-  }
-
-  int Start() override {
-    int ret = epoll_fd_.Create();
-    if (ret < 0) {
-      LOG(ERROR) << "Failed to create epoll fd: %s", strerror(-ret);
-      return -1;
-    }
-
-    // Create the reader thread.
-    reader_thread_ = std::thread([this]() {
-      int ret = dvr_.Api().PerformanceSetSchedulerPolicy(0, "graphics");
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to set scheduler policy, ret=" << ret;
-        return;
-      }
-
-      stopped_.store(false);
-      LOG(INFO) << "Reader Thread Running...";
-
-      while (!stopped_.load()) {
-        std::array<epoll_event, kMaxQueueCounts> events;
-
-        // Don't sleep forever so that we will have a chance to wake up.
-        const int ret = epoll_fd_.Wait(events.data(), events.size(),
-                                       /*timeout=*/100);
-        if (ret < 0) {
-          LOG(ERROR) << "Error polling consumer queues.";
-          continue;
-        }
-        if (ret == 0) {
-          continue;
-        }
-
-        const int num_events = ret;
-        for (int i = 0; i < num_events; i++) {
-          uint32_t index = events[i].data.u32;
-          dvr_.Api().ReadBufferQueueHandleEvents(
-              buffer_queues_[index]->GetReadQueue());
-        }
-      }
-
-      LOG(INFO) << "Reader Thread Exiting...";
-    });
-
-    return 0;
-  }
-
-  sp<Surface> CreateSurface() override {
-    auto new_queue = std::make_shared<BufferQueueHolder>();
-    if (!new_queue->IsReady()) {
-      LOG(ERROR) << "Failed to create BufferHub-based BufferQueue.";
-      return nullptr;
-    }
-
-    // Set buffer dimension.
-    ANativeWindow_setBuffersGeometry(new_queue->GetSurface(), kBufferWidth,
-                                     kBufferHeight, kBufferFormat);
-
-    // Use the next position as buffer_queue index.
-    uint32_t index = buffer_queues_.size();
-    epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u32 = index}};
-    int queue_fd =
-        dvr_.Api().ReadBufferQueueGetEventFd(new_queue->GetReadQueue());
-    const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, queue_fd, &event);
-    if (ret < 0) {
-      LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret)
-                 << ", consumer queue fd: " << queue_fd;
-      return nullptr;
-    }
-
-    buffer_queues_.push_back(new_queue);
-    ANativeWindow_acquire(new_queue->GetSurface());
-    return static_cast<Surface*>(new_queue->GetSurface());
-  }
-
- private:
-  struct BufferQueueHolder {
-    BufferQueueHolder() {
-      int ret = 0;
-      ret = dvr_.Api().WriteBufferQueueCreate(
-          kBufferWidth, kBufferHeight, kBufferFormat, kBufferLayer,
-          kBufferUsage, 0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create write buffer queue, ret=" << ret;
-        return;
-      }
-
-      ret = dvr_.Api().WriteBufferQueueCreateReadQueue(write_queue_,
-                                                       &read_queue_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create read buffer queue, ret=" << ret;
-        return;
-      }
-
-      ret = dvr_.Api().ReadBufferQueueSetBufferAvailableCallback(
-          read_queue_, BufferAvailableCallback, this);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create buffer available callback, ret=" << ret;
-        return;
-      }
-
-      ret =
-          dvr_.Api().WriteBufferQueueGetANativeWindow(write_queue_, &surface_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create surface, ret=" << ret;
-        return;
-      }
-    }
-
-    static void BufferAvailableCallback(void* context) {
-      BufferQueueHolder* thiz = static_cast<BufferQueueHolder*>(context);
-      thiz->HandleBufferAvailable();
-    }
-
-    DvrReadBufferQueue* GetReadQueue() { return read_queue_; }
-
-    ANativeWindow* GetSurface() { return surface_; }
-
-    bool IsReady() {
-      return write_queue_ != nullptr && read_queue_ != nullptr &&
-             surface_ != nullptr;
-    }
-
-    void HandleBufferAvailable() {
-      int ret = 0;
-      DvrNativeBufferMetadata meta;
-      DvrReadBuffer* buffer = nullptr;
-      DvrNativeBufferMetadata metadata;
-      int acquire_fence = kInvalidFence;
-
-      {
-        ATRACE_NAME("AcquireBuffer");
-        ret = dvr_.Api().ReadBufferQueueAcquireBuffer(
-            read_queue_, 0, &buffer, &metadata, &acquire_fence);
-      }
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to acquire consumer buffer, error: " << ret;
-        return;
-      }
-
-      if (buffer != nullptr) {
-        ATRACE_NAME("ReleaseBuffer");
-        ret = dvr_.Api().ReadBufferQueueReleaseBuffer(read_queue_, buffer,
-                                                      &meta, kInvalidFence);
-      }
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to release consumer buffer, error: " << ret;
-      }
-    }
-
-   private:
-    DvrWriteBufferQueue* write_queue_ = nullptr;
-    DvrReadBufferQueue* read_queue_ = nullptr;
-    ANativeWindow* surface_ = nullptr;
-  };
-
-  static DvrApi dvr_;
-  std::atomic<bool> stopped_;
-  std::thread reader_thread_;
-
-  dvr::EpollFileDescriptor epoll_fd_;
-  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-DvrApi BufferHubTransport::dvr_ = {};
-
-enum TransportType {
-  kBinderBufferTransport,
-  kBufferHubTransport,
-};
-
-// Main test suite, which supports two transport backend: 1) BinderBufferQueue,
-// 2) BufferHubQueue. The test case drives the producer end of both transport
-// backend by queuing buffers into the buffer queue by using ANativeWindow API.
-class BufferTransportBenchmark : public ::benchmark::Fixture {
- public:
-  void SetUp(State& state) override {
-    if (state.thread_index == 0) {
-      const int transport = state.range(0);
-      switch (transport) {
-        case kBinderBufferTransport:
-          transport_.reset(new BinderBufferTransport);
-          break;
-        case kBufferHubTransport:
-          transport_.reset(new BufferHubTransport);
-          break;
-        default:
-          CHECK(false) << "Unknown test case.";
-          break;
-      }
-
-      CHECK(transport_);
-      const int ret = transport_->Start();
-      CHECK_EQ(ret, 0);
-
-      LOG(INFO) << "Transport backend running, transport=" << transport << ".";
-
-      // Create surfaces for each thread.
-      surfaces_.resize(state.threads);
-      for (int i = 0; i < state.threads; i++) {
-        // Common setup every thread needs.
-        surfaces_[i] = transport_->CreateSurface();
-        CHECK(surfaces_[i]);
-
-        LOG(INFO) << "Surface initialized on thread " << i << ".";
-      }
-    }
-  }
-
-  void TearDown(State& state) override {
-    if (state.thread_index == 0) {
-      surfaces_.clear();
-      transport_.reset();
-      LOG(INFO) << "Tear down benchmark.";
-    }
-  }
-
- protected:
-  std::unique_ptr<BufferTransport> transport_;
-  std::vector<sp<Surface>> surfaces_;
-};
-
-BENCHMARK_DEFINE_F(BufferTransportBenchmark, Producers)(State& state) {
-  ANativeWindow* window = nullptr;
-  ANativeWindow_Buffer buffer;
-  int32_t error = 0;
-  double total_gain_buffer_us = 0;
-  double total_post_buffer_us = 0;
-  int iterations = 0;
-
-  while (state.KeepRunning()) {
-    if (window == nullptr) {
-      CHECK(surfaces_[state.thread_index]);
-      window = static_cast<ANativeWindow*>(surfaces_[state.thread_index].get());
-
-      // Lock buffers a couple time from the queue, so that we have the buffer
-      // allocated.
-      for (int i = 0; i < kQueueDepth; i++) {
-        error = ANativeWindow_lock(window, &buffer,
-                                   /*inOutDirtyBounds=*/nullptr);
-        CHECK_EQ(error, 0);
-        error = ANativeWindow_unlockAndPost(window);
-        CHECK_EQ(error, 0);
-      }
-    }
-
-    {
-      ATRACE_NAME("GainBuffer");
-      auto t1 = std::chrono::high_resolution_clock::now();
-      error = ANativeWindow_lock(window, &buffer,
-                                 /*inOutDirtyBounds=*/nullptr);
-      auto t2 = std::chrono::high_resolution_clock::now();
-      std::chrono::duration<double, std::micro> delta_us = t2 - t1;
-      total_gain_buffer_us += delta_us.count();
-    }
-    CHECK_EQ(error, 0);
-
-    {
-      ATRACE_NAME("PostBuffer");
-      auto t1 = std::chrono::high_resolution_clock::now();
-      error = ANativeWindow_unlockAndPost(window);
-      auto t2 = std::chrono::high_resolution_clock::now();
-      std::chrono::duration<double, std::micro> delta_us = t2 - t1;
-      total_post_buffer_us += delta_us.count();
-    }
-    CHECK_EQ(error, 0);
-
-    iterations++;
-  }
-
-  state.counters["gain_buffer_us"] = ::benchmark::Counter(
-      total_gain_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
-  state.counters["post_buffer_us"] = ::benchmark::Counter(
-      total_post_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
-  state.counters["producer_us"] = ::benchmark::Counter(
-      (total_gain_buffer_us + total_post_buffer_us) / iterations,
-      ::benchmark::Counter::kAvgThreads);
-}
-
-BENCHMARK_REGISTER_F(BufferTransportBenchmark, Producers)
-    ->Unit(::benchmark::kMicrosecond)
-    ->Ranges({{kBinderBufferTransport, kBufferHubTransport}})
-    ->ThreadRange(1, 32);
-
-static void runBinderServer() {
-  ProcessState::self()->setThreadPoolMaxThreadCount(0);
-  ProcessState::self()->startThreadPool();
-
-  sp<IServiceManager> sm = defaultServiceManager();
-  sp<BufferTransportService> service = new BufferTransportService;
-  sm->addService(kBinderService, service, false);
-
-  LOG(INFO) << "Binder server running...";
-
-  while (true) {
-    int stat, retval;
-    retval = wait(&stat);
-    if (retval == -1 && errno == ECHILD) {
-      break;
-    }
-  }
-
-  LOG(INFO) << "Service Exiting...";
-}
-
-// To run binder-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-//   --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/0/"
-//
-// To run bufferhub-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-//   --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/1/"
-int main(int argc, char** argv) {
-  bool tracing_enabled = false;
-
-  // Parse arguments in addition to "--benchmark_filter" paramters.
-  for (int i = 1; i < argc; i++) {
-    if (std::string(argv[i]) == "--help") {
-      std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl;
-      std::cout << "\t--trace: Enable systrace logging." << std::endl;
-      return 0;
-    }
-    if (std::string(argv[i]) == "--trace") {
-      tracing_enabled = true;
-      continue;
-    }
-  }
-
-  // Setup ATRACE/systrace based on command line.
-  atrace_setup();
-  atrace_set_tracing_enabled(tracing_enabled);
-
-  pid_t pid = fork();
-  if (pid == 0) {
-    // Child, i.e. the client side.
-    ProcessState::self()->startThreadPool();
-
-    ::benchmark::Initialize(&argc, argv);
-    ::benchmark::RunSpecifiedBenchmarks();
-  } else {
-    LOG(INFO) << "Benchmark process pid: " << pid;
-    runBinderServer();
-  }
-}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index 33a0d75..e373376 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -48,19 +48,3 @@
     ],
     name: "buffer_hub_queue-test",
 }
-
-cc_test {
-    srcs: ["buffer_hub_queue_producer-test.cpp"],
-    header_libs: header_libraries,
-    static_libs: static_libraries,
-    shared_libs: shared_libraries,
-    cflags: [
-        "-DLOG_TAG=\"buffer_hub_queue_producer-test\"",
-        "-DTRACE=0",
-        "-O0",
-        "-g",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "buffer_hub_queue_producer-test",
-}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
deleted file mode 100644
index fab1097..0000000
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-#include <base/logging.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <pdx/default_transport/channel_parcelable.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-using pdx::LocalHandle;
-
-namespace {
-
-// Default dimensions before setDefaultBufferSize is called by the consumer.
-constexpr uint32_t kDefaultWidth = 1;
-constexpr uint32_t kDefaultHeight = 1;
-
-// Default format before setDefaultBufferFormat is called by the consumer.
-constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-constexpr int kDefaultConsumerUsageBits = 0;
-
-// Default transform hint before setTransformHint is called by the consumer.
-constexpr uint32_t kDefaultTransformHint = 0;
-
-constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
-constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
-constexpr int kTestApiInvalid = 0xDEADBEEF;
-constexpr int kTestProducerUsageBits = 0;
-constexpr bool kTestControlledByApp = true;
-
-// Builder pattern to slightly vary *almost* correct input
-// -- avoids copying and pasting
-struct QueueBufferInputBuilder {
-  IGraphicBufferProducer::QueueBufferInput build() {
-    return IGraphicBufferProducer::QueueBufferInput(
-        mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
-        mTransform, mFence);
-  }
-
-  QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
-    this->mTimestamp = timestamp;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
-    this->mIsAutoTimestamp = isAutoTimestamp;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
-    this->mDataSpace = dataSpace;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setCrop(Rect crop) {
-    this->mCrop = crop;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setScalingMode(int scalingMode) {
-    this->mScalingMode = scalingMode;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setTransform(uint32_t transform) {
-    this->mTransform = transform;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setFence(sp<Fence> fence) {
-    this->mFence = fence;
-    return *this;
-  }
-
- private:
-  int64_t mTimestamp{1384888611};
-  bool mIsAutoTimestamp{false};
-  android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
-  Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
-  int mScalingMode{0};
-  uint32_t mTransform{0};
-  sp<Fence> mFence{Fence::NO_FENCE};
-};
-
-// This is a test that covers our implementation of bufferhubqueue-based
-// IGraphicBufferProducer.
-class BufferHubQueueProducerTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    const ::testing::TestInfo* const testInfo =
-        ::testing::UnitTest::GetInstance()->current_test_info();
-    ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
-             testInfo->name());
-
-    auto config = ProducerQueueConfigBuilder().Build();
-    auto queue = ProducerQueue::Create(config, UsagePolicy{});
-    ASSERT_TRUE(queue != nullptr);
-
-    mProducer = BufferHubProducer::Create(std::move(queue));
-    ASSERT_TRUE(mProducer != nullptr);
-    mSurface = new Surface(mProducer, true);
-    ASSERT_TRUE(mSurface != nullptr);
-  }
-
-  // Connect to a producer in a 'correct' fashion.
-  void ConnectProducer() {
-    IGraphicBufferProducer::QueueBufferOutput output;
-    // Can connect the first time.
-    ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi,
-                                     kTestControlledByApp, &output));
-  }
-
-  // Dequeue a buffer in a 'correct' fashion.
-  //   Precondition: Producer is connected.
-  void DequeueBuffer(int* outSlot) {
-    sp<Fence> fence;
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
-  }
-
-  void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
-    ASSERT_NE(nullptr, outSlot);
-    ASSERT_NE(nullptr, outFence);
-
-    int ret = mProducer->dequeueBuffer(
-        outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat,
-        kTestProducerUsageBits, nullptr, nullptr);
-    // BUFFER_NEEDS_REALLOCATION can be either on or off.
-    ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);
-
-    // Slot number should be in boundary.
-    ASSERT_LE(0, *outSlot);
-    ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
-  }
-
-  // Create a generic "valid" input for queueBuffer
-  // -- uses the default buffer format, width, etc.
-  static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
-    return QueueBufferInputBuilder().build();
-  }
-
-  const sp<IProducerListener> kStubListener{new StubProducerListener};
-
-  sp<BufferHubProducer> mProducer;
-  sp<Surface> mSurface;
-};
-
-TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // NULL output returns BAD_VALUE
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
-                                          kTestControlledByApp, nullptr));
-
-  // Invalid API returns bad value
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid,
-                                          kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Can't connect when there is already a producer connected.
-  IGraphicBufferProducer::QueueBufferOutput output;
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
-                                          kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Must disconnect with same API number
-  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
-  // API must not be out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int32_t value = -1;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
-  EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
-  EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
-  EXPECT_EQ(kDefaultFormat, value);
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
-  EXPECT_LE(0, value);
-  EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value);
-
-  EXPECT_EQ(OK,
-            mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
-  EXPECT_FALSE(value);  // Can't run behind when we haven't touched the queue
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
-  EXPECT_EQ(kDefaultConsumerUsageBits, value);
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // One past the end of the last 'query' enum value. Update this if we add more
-  // enums.
-  const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
-
-  int value;
-  // What was out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
-
-  // Some enums from window.h are 'invalid'
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
-
-  // Value was NULL
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
-}
-
-TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  // Request the buffer (pre-requisite for queueing)
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // Queue the buffer back into the BQ
-  ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
-  EXPECT_EQ(kDefaultWidth, output.width);
-  EXPECT_EQ(kDefaultHeight, output.height);
-  EXPECT_EQ(kDefaultTransformHint, output.transformHint);
-
-  // BufferHubQueue delivers buffers to consumer immediately.
-  EXPECT_EQ(0u, output.numPendingBuffers);
-
-  // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
-  // be a SurfaceFlinger specific optimization.
-  EXPECT_EQ(0u, output.nextFrameNumber);
-
-  // Buffer was not in the dequeued state
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test invalid slot number
-TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
-                                              input, &output));
-}
-
-// Slot was not in the dequeued state (all slots start out in Free state)
-TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
-}
-
-// Slot was enqueued without requesting a buffer
-TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test when fence was NULL
-TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  sp<Fence> nullFence = NULL;
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder().setFence(nullFence).build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test scaling mode was invalid
-TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder().setScalingMode(-1).build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-
-  input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test crop rect is out of bounds of the buffer dimensions
-TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder()
-          .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
-          .build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
-  int slot = -1;
-  sp<Fence> fence;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
-
-  // Should be able to cancel buffer after a dequeue.
-  EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
-  return;
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int minUndequeuedBuffers;
-  ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-
-  const int minBuffers = 1;
-  const int maxBuffers =
-      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
-  ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers))
-      << "bufferCount: " << minBuffers;
-
-  // Should now be able to dequeue up to minBuffers times
-  // Should now be able to dequeue up to maxBuffers times
-  int slot = -1;
-  for (int i = 0; i < minBuffers; ++i) {
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  }
-
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers));
-
-  // queue the first buffer to enable max dequeued buffer count checking
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-  ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
-  sp<Fence> fence;
-  for (int i = 0; i < maxBuffers; ++i) {
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
-  }
-
-  // Cancel a buffer, so we can decrease the buffer count
-  ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-
-  // Should now be able to decrease the max dequeued count by 1
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int minUndequeuedBuffers;
-  ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-
-  const int minBuffers = 1;
-  const int maxBuffers =
-      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
-  ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
-  // Buffer count was out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
-      << "bufferCount: " << 0;
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
-      << "bufferCount: " << maxBuffers + 1;
-
-  // Set max dequeue count to 2
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
-  // Dequeue 2 buffers
-  int slot = -1;
-  sp<Fence> fence;
-  for (int i = 0; i < 2; i++) {
-    ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
-                      (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
-                                                kDefaultHeight, kDefaultFormat,
-                                                kTestProducerUsageBits,
-                                                nullptr, nullptr)))
-        << "slot: " << slot;
-  }
-
-  // Client has too many buffers dequeued
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
-      << "bufferCount: " << minBuffers;
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_dequeueBuffer) {
-  int slot = -1;
-  sp<Fence> fence;
-
-  ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
-                                              kDefaultHeight, kDefaultFormat,
-                                              kTestProducerUsageBits,
-                                              nullptr, nullptr));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_requestBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  // Shouldn't be able to request buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_queueBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // Shouldn't be able to queue buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_cancelBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // Shouldn't be able to cancel buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectDisconnectReconnect) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
-  constexpr int maxDequeuedBuffers = 1;
-  int minUndequeuedBuffers;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-  EXPECT_EQ(OK, mProducer->setAsyncMode(false));
-  EXPECT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers));
-
-  int maxCapacity = maxDequeuedBuffers + minUndequeuedBuffers;
-
-  // Dequeue, request, and queue all buffers.
-  for (int i = 0; i < maxCapacity; i++) {
-    EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-    EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-    EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-  }
-
-  // Disconnect then reconnect.
-  EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Dequeue, request, and queue all buffers.
-  for (int i = 0; i < maxCapacity; i++) {
-    EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-    EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-    EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-  }
-
-  EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) {
-  // Connected producer cannot be taken out as a parcelable.
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-  ProducerQueueParcelable producer_parcelable;
-  EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE);
-
-  // Create a valid fake producer parcelable.
-  auto fake_channel_parcelable =
-      std::make_unique<pdx::default_transport::ChannelParcelable>(
-          LocalHandle(0), LocalHandle(0), LocalHandle(0));
-  EXPECT_TRUE(fake_channel_parcelable->IsValid());
-  ProducerQueueParcelable fake_producer_parcelable(
-      std::move(fake_channel_parcelable));
-  EXPECT_TRUE(fake_producer_parcelable.IsValid());
-
-  // Disconnect producer can be taken out, but only to an invalid parcelable.
-  ASSERT_EQ(mProducer->disconnect(kTestApi), OK);
-  EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE);
-  EXPECT_FALSE(producer_parcelable.IsValid());
-  EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK);
-  EXPECT_TRUE(producer_parcelable.IsValid());
-
-  // Should still be able to query buffer dimension after disconnect.
-  int32_t value = -1;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
-  EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth);
-
-  EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK);
-  EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight);
-
-  EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK);
-  EXPECT_EQ(value, kDefaultFormat);
-
-  // But connect to API will fail.
-  IGraphicBufferProducer::QueueBufferOutput output;
-  EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp,
-                               &output),
-            BAD_VALUE);
-
-  // Create a new producer from the parcelable and connect to kTestApi should
-  // succeed.
-  sp<BufferHubProducer> new_producer =
-      BufferHubProducer::Create(std::move(producer_parcelable));
-  ASSERT_TRUE(new_producer != nullptr);
-  EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp,
-                                  &output),
-            OK);
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 96023dd..9dbeacb 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -33,87 +33,3 @@
     ],
     min_sdk_version: "29",
 }
-
-cc_library_headers {
-    name: "libdvr_private_headers",
-    export_include_dirs: ["."],
-    vendor_available: false,
-}
-
-cflags = [
-    "-DDVR_TRACKING_IMPLEMENTED=0",
-    "-DLOG_TAG=\"libdvr\"",
-    "-DTRACE=0",
-    "-Wall",
-    "-Werror",
-]
-
-srcs = [
-    "dvr_api.cpp",
-    "dvr_buffer.cpp",
-    "dvr_buffer_queue.cpp",
-    "dvr_configuration_data.cpp",
-    "dvr_display_manager.cpp",
-    "dvr_hardware_composer_client.cpp",
-    "dvr_performance.cpp",
-    "dvr_pose.cpp",
-    "dvr_surface.cpp",
-    "dvr_tracking.cpp",
-]
-
-static_libs = [
-    "libbroadcastring",
-    "libvrsensor",
-    "libdisplay",
-    "libvirtualtouchpadclient",
-    "libvr_hwc-impl",
-    "libvr_hwc-binder",
-    "libgrallocusage",
-    "libperformance",
-]
-
-shared_libs = [
-    "android.hardware.graphics.bufferqueue@1.0",
-    "android.hidl.token@1.0-utils",
-    "libbase",
-    "libbufferhubqueue",
-    "libbinder",
-    "liblog",
-    "libcutils",
-    "libutils",
-    "libnativewindow",
-    "libgui",
-    "libui",
-    "libpdx_default_transport",
-]
-
-cc_library_shared {
-    name: "libdvr.google",
-    system_ext_specific: true,
-    owner: "google",
-    cflags: cflags,
-    header_libs: ["libdvr_headers"],
-    export_header_lib_headers: ["libdvr_headers"],
-    srcs: srcs,
-    static_libs: static_libs,
-    shared_libs: shared_libs,
-    version_script: "exported_apis.lds",
-}
-
-// Also build a static libdvr for linking into tests. The linker script
-// restricting function access in the shared lib makes it inconvenient to use in
-// test code.
-cc_library_static {
-    name: "libdvr_static.google",
-    owner: "google",
-    cflags: cflags,
-    header_libs: ["libdvr_headers"],
-    export_header_lib_headers: ["libdvr_headers"],
-    srcs: srcs,
-    static_libs: static_libs,
-    shared_libs: shared_libs,
-}
-
-subdirs = [
-    "tests",
-]
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
deleted file mode 100644
index e099f6a..0000000
--- a/libs/vr/libdvr/dvr_api.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "include/dvr/dvr_api.h"
-
-#include <errno.h>
-#include <utils/Log.h>
-
-#include <algorithm>
-
-// Headers from libdvr
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_buffer_queue.h>
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_performance.h>
-#include <dvr/dvr_surface.h>
-#include <dvr/dvr_tracking.h>
-#include <dvr/dvr_vsync.h>
-
-// Headers not yet moved into libdvr.
-// TODO(jwcai) Move these once their callers are moved into Google3.
-#include <dvr/dvr_hardware_composer_client.h>
-#include <dvr/pose_client.h>
-#include <dvr/virtual_touchpad_client.h>
-
-extern "C" {
-
-int dvrGetApi(void* api, size_t struct_size, int version) {
-  ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size,
-        version);
-  if (version == 1) {
-    // New entry points are added at the end. If the caller's struct and
-    // this library have different sizes, we define the entry points in common.
-    // The caller is expected to handle unset entry points if necessary.
-    size_t clamped_struct_size = std::min(struct_size, sizeof(DvrApi_v1));
-    DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api);
-
-// Defines an API entry for V1 (no version suffix).
-#define DVR_V1_API_ENTRY(name)                                 \
-  do {                                                         \
-    if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
-        clamped_struct_size) {                                 \
-      dvr_api->name = dvr##name;                               \
-    }                                                          \
-  } while (0)
-
-#define DVR_V1_API_ENTRY_DEPRECATED(name)                      \
-  do {                                                         \
-    if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
-        clamped_struct_size) {                                 \
-      dvr_api->name = nullptr;                                 \
-    }                                                          \
-  } while (0)
-
-#include "include/dvr/dvr_api_entries.h"
-
-// Undefine macro definitions to play nice with Google3 style rules.
-#undef DVR_V1_API_ENTRY
-#undef DVR_V1_API_ENTRY_DEPRECATED
-
-    return 0;
-  }
-
-  ALOGE("dvrGetApi: Unknown API version=%d", version);
-  return -EINVAL;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
deleted file mode 100644
index c11706f..0000000
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "include/dvr/dvr_buffer.h"
-
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-#include <ui/GraphicBuffer.h>
-
-#include "dvr_internal.h"
-
-using namespace android;
-
-namespace android {
-namespace dvr {
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
-    const std::shared_ptr<IonBuffer>& ion_buffer) {
-  if (!ion_buffer)
-    return nullptr;
-  return new DvrBuffer{std::move(ion_buffer)};
-}
-
-}  // namespace dvr
-}  // namespace android
-
-namespace {
-
-int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
-                             AHardwareBuffer** hardware_buffer) {
-  if (!hardware_buffer || !graphic_buffer) {
-    return -EINVAL;
-  }
-  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(graphic_buffer);
-  AHardwareBuffer_acquire(*hardware_buffer);
-  return 0;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
-  if (write_buffer != nullptr) {
-    ALOGW_IF(
-        write_buffer->slot != -1,
-        "dvrWriteBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
-        dvrWriteBufferGetId(write_buffer));
-    delete write_buffer;
-  }
-}
-
-int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) {
-  return write_buffer && write_buffer->write_buffer;
-}
-
-int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  return write_buffer->write_buffer->id();
-}
-
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
-                                     AHardwareBuffer** hardware_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  return ConvertToAHardwareBuffer(
-      write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) {
-  if (read_buffer != nullptr) {
-    ALOGW_IF(
-        read_buffer->slot != -1,
-        "dvrReadBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
-        dvrReadBufferGetId(read_buffer));
-    delete read_buffer;
-  }
-}
-
-int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) {
-  return read_buffer && read_buffer->read_buffer;
-}
-
-int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  return read_buffer->read_buffer->id();
-}
-
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
-                                    AHardwareBuffer** hardware_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  return ConvertToAHardwareBuffer(
-      read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
-
-int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
-                                AHardwareBuffer** hardware_buffer) {
-  if (!buffer || !buffer->buffer || !hardware_buffer) {
-    return -EINVAL;
-  }
-
-  return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(),
-                                  hardware_buffer);
-}
-
-// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
-int dvrBufferGlobalLayoutVersionGet() {
-  return android::dvr::kSharedBufferLayoutVersion;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
deleted file mode 100644
index 1ca653c..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ /dev/null
@@ -1,552 +0,0 @@
-#include "include/dvr/dvr_api.h"
-#include "include/dvr/dvr_buffer_queue.h"
-
-#include <android/native_window.h>
-#include <gui/BufferHubProducer.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using namespace android;
-using android::dvr::BufferHubBase;
-using android::dvr::ConsumerBuffer;
-using android::dvr::ConsumerQueue;
-using android::dvr::ProducerBuffer;
-using android::dvr::ProducerQueue;
-using android::dvr::ProducerQueueConfigBuilder;
-using android::dvr::UsagePolicy;
-
-extern "C" {
-
-DvrWriteBufferQueue::DvrWriteBufferQueue(
-    const std::shared_ptr<ProducerQueue>& producer_queue)
-    : producer_queue_(producer_queue),
-      width_(producer_queue->default_width()),
-      height_(producer_queue->default_height()),
-      format_(producer_queue->default_format()) {}
-
-int DvrWriteBufferQueue::GetNativeWindow(ANativeWindow** out_window) {
-  if (native_window_ == nullptr) {
-    // Lazy creation of |native_window|, as not everyone is using
-    // DvrWriteBufferQueue as an external surface.
-    sp<IGraphicBufferProducer> gbp = BufferHubProducer::Create(producer_queue_);
-    native_window_ = new Surface(gbp, true);
-  }
-
-  *out_window = static_cast<ANativeWindow*>(native_window_.get());
-  return 0;
-}
-
-int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
-  std::unique_ptr<ConsumerQueue> consumer_queue =
-      producer_queue_->CreateConsumerQueue();
-  if (consumer_queue == nullptr) {
-    ALOGE(
-        "DvrWriteBufferQueue::CreateReadQueue: Failed to create consumer queue "
-        "from producer queue: queue_id=%d.", producer_queue_->id());
-    return -ENOMEM;
-  }
-
-  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
-  return 0;
-}
-
-int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer,
-                                 int* out_fence_fd) {
-  DvrNativeBufferMetadata meta;
-  DvrWriteBuffer* buffer = nullptr;
-  int fence_fd = -1;
-  if (const int ret = GainBuffer(timeout, &buffer, &meta, &fence_fd))
-    return ret;
-  if (!buffer)
-    return -ENOMEM;
-
-  write_buffers_[buffer->slot].reset(buffer);
-  write_buffer->write_buffer = std::move(buffer->write_buffer);
-  *out_fence_fd = fence_fd;
-  return 0;
-}
-
-int DvrWriteBufferQueue::GainBuffer(int timeout,
-                                    DvrWriteBuffer** out_write_buffer,
-                                    DvrNativeBufferMetadata* out_meta,
-                                    int* out_fence_fd) {
-  size_t slot;
-  pdx::LocalHandle release_fence;
-
-  // Need to retry N+1 times, where N is total number of buffers in the queue.
-  // As in the worst case, we will dequeue all N buffers and reallocate them, on
-  // the {N+1}th dequeue, we are guaranteed to get a buffer with new dimension.
-  size_t max_retries = 1 + producer_queue_->capacity();
-  size_t retry = 0;
-
-  for (; retry < max_retries; retry++) {
-    auto buffer_status =
-        producer_queue_->Dequeue(timeout, &slot, out_meta, &release_fence);
-    if (!buffer_status) {
-      ALOGE_IF(buffer_status.error() != ETIMEDOUT,
-               "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer: %s",
-               buffer_status.GetErrorMessage().c_str());
-      return -buffer_status.error();
-    }
-
-    if (write_buffers_[slot] == nullptr) {
-      // Lazy initialization of a write_buffers_ slot. Note that a slot will
-      // only be dynamically allocated once during the entire cycle life of a
-      // queue.
-      write_buffers_[slot] = std::make_unique<DvrWriteBuffer>();
-      write_buffers_[slot]->slot = slot;
-    }
-
-    LOG_ALWAYS_FATAL_IF(
-        write_buffers_[slot]->write_buffer,
-        "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot);
-    write_buffers_[slot]->write_buffer = std::move(buffer_status.take());
-
-    const auto& producer_buffer = write_buffers_[slot]->write_buffer;
-    if (!producer_buffer)
-      return -ENOMEM;
-
-    if (width_ == producer_buffer->width() &&
-        height_ == producer_buffer->height() &&
-        format_ == producer_buffer->format()) {
-      // Producer queue returns a buffer matches the current request.
-      break;
-    }
-
-    // Needs reallocation. Note that if there are already multiple available
-    // buffers in the queue, the next one returned from |queue_->Dequeue| may
-    // still have the old buffer dimension or format. Retry up to N+1 times or
-    // until we dequeued a buffer with new configuration.
-    ALOGD_IF(TRACE,
-             "DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu "
-             "(w=%u, h=%u, fmt=%u) is different from the buffer returned "
-             "(w=%u, h=%u, fmt=%u). Need re-allocation.",
-             slot, width_, height_, format_, producer_buffer->width(),
-             producer_buffer->height(), producer_buffer->format());
-
-    // Currently, we are not storing |layer_count| and |usage| in queue
-    // configuration. Copy those setup from the last buffer dequeued before we
-    // remove it.
-    uint32_t old_layer_count = producer_buffer->layer_count();
-    uint64_t old_usage = producer_buffer->usage();
-
-    // Allocate a new producer buffer with new buffer configs. Note that if
-    // there are already multiple available buffers in the queue, the next one
-    // returned from |queue_->Dequeue| may still have the old buffer dimension
-    // or format. Retry up to BufferHubQueue::kMaxQueueCapacity times or until
-    // we dequeued a buffer with new configuration.
-    auto remove_status = producer_queue_->RemoveBuffer(slot);
-    if (!remove_status) {
-      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to remove buffer: %s",
-            remove_status.GetErrorMessage().c_str());
-      return -remove_status.error();
-    }
-    // Make sure that the previously allocated buffer is dereferenced from
-    // write_buffers_ array.
-    write_buffers_[slot]->write_buffer = nullptr;
-
-    auto allocate_status = producer_queue_->AllocateBuffer(
-        width_, height_, old_layer_count, format_, old_usage);
-    if (!allocate_status) {
-      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to allocate buffer: %s",
-            allocate_status.GetErrorMessage().c_str());
-      return -allocate_status.error();
-    }
-  }
-
-  if (retry >= max_retries) {
-    ALOGE(
-        "DvrWriteBufferQueue::Dequeue: Failed to re-allocate buffer after "
-        "resizing.");
-    return -ENOMEM;
-  }
-
-  *out_write_buffer = write_buffers_[slot].release();
-  *out_fence_fd = release_fence.Release();
-
-  return 0;
-}
-
-int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer,
-                                    const DvrNativeBufferMetadata* meta,
-                                    int ready_fence_fd) {
-  // Some basic sanity checks before we put the buffer back into a slot.
-  size_t slot = static_cast<size_t>(write_buffer->slot);
-  LOG_FATAL_IF(
-      (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()),
-      "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
-  if (write_buffers_[slot] != nullptr) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot);
-    return -EINVAL;
-  }
-  if (write_buffer->write_buffer == nullptr) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer.");
-    return -EINVAL;
-  }
-  if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) {
-    ALOGE(
-        "DvrWriteBufferQueue::PostBuffer: Buffer to be posted does not "
-        "belong to this buffer queue. Posting buffer: id=%d, buffer in "
-        "queue: id=%d",
-        write_buffer->write_buffer->id(), producer_queue_->GetBufferId(slot));
-    return -EINVAL;
-  }
-
-  write_buffer->write_buffer->SetQueueIndex(next_post_index_++);
-  pdx::LocalHandle fence(ready_fence_fd);
-  const int ret = write_buffer->write_buffer->PostAsync(meta, fence);
-  if (ret < 0) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d",
-          ret);
-    return ret;
-  }
-
-  // Put the DvrWriteBuffer pointer back into its slot for reuse.
-  write_buffers_[slot].reset(write_buffer);
-  // It's import to reset the write buffer client now. It should stay invalid
-  // until next GainBuffer on the same slot.
-  write_buffers_[slot]->write_buffer = nullptr;
-  return 0;
-}
-
-int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) {
-  if (width == 0 || height == 0) {
-    ALOGE(
-        "DvrWriteBufferQueue::ResizeBuffer: invalid buffer dimension: w=%u, "
-        "h=%u.",
-        width, height);
-    return -EINVAL;
-  }
-
-  width_ = width;
-  height_ = height;
-  return 0;
-}
-
-int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format,
-                              uint32_t layer_count, uint64_t usage,
-                              size_t capacity, size_t metadata_size,
-                              DvrWriteBufferQueue** out_write_queue) {
-  if (!out_write_queue)
-    return -EINVAL;
-
-  auto config_builder = ProducerQueueConfigBuilder()
-                            .SetDefaultWidth(width)
-                            .SetDefaultHeight(height)
-                            .SetDefaultFormat(format)
-                            .SetMetadataSize(metadata_size);
-  std::unique_ptr<ProducerQueue> producer_queue =
-      ProducerQueue::Create(config_builder.Build(), UsagePolicy{});
-  if (!producer_queue) {
-    ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue.");
-    return -ENOMEM;
-  }
-
-  auto status = producer_queue->AllocateBuffers(width, height, layer_count,
-                                                format, usage, capacity);
-  if (!status.ok()) {
-    ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers.");
-    return -ENOMEM;
-  }
-
-  *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue));
-  return 0;
-}
-
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
-  delete write_queue;
-}
-
-ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->capacity();
-}
-
-int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->id();
-}
-
-int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
-                                        ANativeWindow** out_window) {
-  if (!write_queue || !out_window)
-    return -EINVAL;
-
-  return write_queue->GetNativeWindow(out_window);
-}
-
-int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
-                                       DvrReadBufferQueue** out_read_queue) {
-  if (!write_queue || !out_read_queue)
-    return -EINVAL;
-
-  return write_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
-                                  DvrWriteBuffer** out_write_buffer,
-                                  DvrNativeBufferMetadata* out_meta,
-                                  int* out_fence_fd) {
-  if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd)
-    return -EINVAL;
-
-  return write_queue->GainBuffer(timeout, out_write_buffer, out_meta,
-                                 out_fence_fd);
-}
-
-int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
-                                  DvrWriteBuffer* write_buffer,
-                                  const DvrNativeBufferMetadata* meta,
-                                  int ready_fence_fd) {
-  if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta)
-    return -EINVAL;
-
-  return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd);
-}
-
-int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
-                                    uint32_t width, uint32_t height) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->ResizeBuffer(width, height);
-}
-
-// ReadBufferQueue
-
-DvrReadBufferQueue::DvrReadBufferQueue(
-    const std::shared_ptr<ConsumerQueue>& consumer_queue)
-    : consumer_queue_(consumer_queue) {}
-
-int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
-  std::unique_ptr<ConsumerQueue> consumer_queue =
-      consumer_queue_->CreateConsumerQueue();
-  if (consumer_queue == nullptr) {
-    ALOGE(
-        "DvrReadBufferQueue::CreateReadQueue: Failed to create consumer queue "
-        "from producer queue: queue_id=%d.", consumer_queue_->id());
-    return -ENOMEM;
-  }
-
-  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
-  return 0;
-}
-
-int DvrReadBufferQueue::AcquireBuffer(int timeout,
-                                      DvrReadBuffer** out_read_buffer,
-                                      DvrNativeBufferMetadata* out_meta,
-                                      int* out_fence_fd) {
-  size_t slot;
-  pdx::LocalHandle acquire_fence;
-  auto buffer_status =
-      consumer_queue_->Dequeue(timeout, &slot, out_meta, &acquire_fence);
-  if (!buffer_status) {
-    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
-             "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer: %s",
-             buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  if (read_buffers_[slot] == nullptr) {
-    // Lazy initialization of a read_buffers_ slot. Note that a slot will only
-    // be dynamically allocated once during the entire cycle life of a queue.
-    read_buffers_[slot] = std::make_unique<DvrReadBuffer>();
-    read_buffers_[slot]->slot = slot;
-  }
-
-  LOG_FATAL_IF(
-      read_buffers_[slot]->read_buffer,
-      "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot);
-  read_buffers_[slot]->read_buffer = std::move(buffer_status.take());
-
-  *out_read_buffer = read_buffers_[slot].release();
-  *out_fence_fd = acquire_fence.Release();
-
-  return 0;
-}
-
-int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer,
-                                      const DvrNativeBufferMetadata* meta,
-                                      int release_fence_fd) {
-  // Some basic sanity checks before we put the buffer back into a slot.
-  size_t slot = static_cast<size_t>(read_buffer->slot);
-  LOG_FATAL_IF(
-      (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()),
-      "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
-  if (read_buffers_[slot] != nullptr) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot);
-    return -EINVAL;
-  }
-  if (read_buffer->read_buffer == nullptr) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer.");
-    return -EINVAL;
-  }
-  if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) {
-    if (consumer_queue_->GetBufferId(slot) > 0) {
-      ALOGE(
-          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
-          "belong to this queue (queue_id=%d): attempting to release buffer "
-          "(buffer_id=%d) at slot %d which holds a different buffer "
-          "(buffer_id=%d).",
-          consumer_queue_->id(), read_buffer->read_buffer->id(),
-          static_cast<int>(slot), consumer_queue_->GetBufferId(slot));
-    } else {
-      ALOGI(
-          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
-          "belong to this queue (queue_id=%d): attempting to release buffer "
-          "(buffer_id=%d) at slot %d which is empty.",
-          consumer_queue_->id(), read_buffer->read_buffer->id(),
-          static_cast<int>(slot));
-    }
-  }
-
-  pdx::LocalHandle fence(release_fence_fd);
-  int ret = read_buffer->read_buffer->ReleaseAsync(meta, fence);
-  if (ret < 0) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d",
-          ret);
-    return ret;
-  }
-
-  // Put the DvrReadBuffer pointer back into its slot for reuse.
-  read_buffers_[slot].reset(read_buffer);
-  // It's import to reset the read buffer client now. It should stay invalid
-  // until next AcquireBuffer on the same slot.
-  read_buffers_[slot]->read_buffer = nullptr;
-  return 0;
-}
-
-void DvrReadBufferQueue::SetBufferAvailableCallback(
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
-  if (callback == nullptr) {
-    consumer_queue_->SetBufferAvailableCallback(nullptr);
-  } else {
-    consumer_queue_->SetBufferAvailableCallback(
-        [callback, context]() { callback(context); });
-  }
-}
-
-void DvrReadBufferQueue::SetBufferRemovedCallback(
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
-  if (callback == nullptr) {
-    consumer_queue_->SetBufferRemovedCallback(nullptr);
-  } else {
-    consumer_queue_->SetBufferRemovedCallback(
-        [callback, context](const std::shared_ptr<BufferHubBase>& buffer) {
-          // When buffer is removed from the queue, the slot is already invalid.
-          auto read_buffer = std::make_unique<DvrReadBuffer>();
-          read_buffer->read_buffer =
-              std::static_pointer_cast<ConsumerBuffer>(buffer);
-          callback(read_buffer.release(), context);
-        });
-  }
-}
-
-int DvrReadBufferQueue::HandleEvents() {
-  // TODO(jwcai) Probably should change HandleQueueEvents to return Status.
-  consumer_queue_->HandleQueueEvents();
-  return 0;
-}
-
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
-  delete read_queue;
-}
-
-ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->capacity();
-}
-
-int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->id();
-}
-
-int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->event_fd();
-}
-
-int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
-                                      DvrReadBufferQueue** out_read_queue) {
-  if (!read_queue || !out_read_queue)
-    return -EINVAL;
-
-  return read_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
-                              DvrReadBuffer* read_buffer, int* out_fence_fd,
-                              void* out_meta, size_t meta_size_bytes) {
-  if (!read_queue || !read_buffer || !out_fence_fd)
-    return -EINVAL;
-
-  if (meta_size_bytes != 0 && !out_meta)
-    return -EINVAL;
-
-  return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta,
-                             meta_size_bytes);
-}
-
-int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
-                                    DvrReadBuffer** out_read_buffer,
-                                    DvrNativeBufferMetadata* out_meta,
-                                    int* out_fence_fd) {
-  if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd)
-    return -EINVAL;
-
-  return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta,
-                                   out_fence_fd);
-}
-
-int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
-                                    DvrReadBuffer* read_buffer,
-                                    const DvrNativeBufferMetadata* meta,
-                                    int release_fence_fd) {
-  if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta)
-    return -EINVAL;
-
-  return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd);
-}
-
-int dvrReadBufferQueueSetBufferAvailableCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
-  if (!read_queue)
-    return -EINVAL;
-
-  read_queue->SetBufferAvailableCallback(callback, context);
-  return 0;
-}
-
-int dvrReadBufferQueueSetBufferRemovedCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
-  if (!read_queue)
-    return -EINVAL;
-
-  read_queue->SetBufferRemovedCallback(callback, context);
-  return 0;
-}
-
-int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->HandleEvents();
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h
deleted file mode 100644
index e53a686..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue_internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-#define ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-
-#include <gui/Surface.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <sys/cdefs.h>
-
-#include <array>
-#include <memory>
-
-#include "dvr_internal.h"
-
-struct ANativeWindow;
-
-typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
-                                                        void* context);
-
-struct DvrWriteBufferQueue {
-  using BufferHubQueue = android::dvr::BufferHubQueue;
-  using ProducerQueue = android::dvr::ProducerQueue;
-
-  // Create a concrete object for DvrWriteBufferQueue.
-  //
-  // @param producer_queue The BufferHub's ProducerQueue that is used to back
-  //     this DvrWriteBufferQueue, must not be NULL.
-  explicit DvrWriteBufferQueue(
-      const std::shared_ptr<ProducerQueue>& producer_queue);
-
-  int id() const { return producer_queue_->id(); }
-  uint32_t width() const { return width_; };
-  uint32_t height() const { return height_; };
-  uint32_t format() const { return format_; };
-  size_t capacity() const { return producer_queue_->capacity(); }
-  const std::shared_ptr<ProducerQueue>& producer_queue() const {
-    return producer_queue_;
-  }
-
-  int GetNativeWindow(ANativeWindow** out_window);
-  int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
-  int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd);
-  int GainBuffer(int timeout, DvrWriteBuffer** out_write_buffer,
-                 DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
-  int PostBuffer(DvrWriteBuffer* write_buffer,
-                 const DvrNativeBufferMetadata* meta, int ready_fence_fd);
-  int ResizeBuffer(uint32_t width, uint32_t height);
-
- private:
-  std::shared_ptr<ProducerQueue> producer_queue_;
-  std::array<std::unique_ptr<DvrWriteBuffer>, BufferHubQueue::kMaxQueueCapacity>
-      write_buffers_;
-
-  int64_t next_post_index_ = 0;
-  uint32_t width_;
-  uint32_t height_;
-  uint32_t format_;
-
-  android::sp<android::Surface> native_window_;
-};
-
-struct DvrReadBufferQueue {
-  using BufferHubQueue = android::dvr::BufferHubQueue;
-  using ConsumerQueue = android::dvr::ConsumerQueue;
-
-  explicit DvrReadBufferQueue(
-      const std::shared_ptr<ConsumerQueue>& consumer_queue);
-
-  int id() const { return consumer_queue_->id(); }
-  int event_fd() const { return consumer_queue_->queue_fd(); }
-  size_t capacity() const { return consumer_queue_->capacity(); }
-
-  int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
-  int Dequeue(int timeout, DvrReadBuffer* read_buffer, int* out_fence_fd,
-              void* out_meta, size_t user_metadata_size);
-  int AcquireBuffer(int timeout, DvrReadBuffer** out_read_buffer,
-                    DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
-  int ReleaseBuffer(DvrReadBuffer* read_buffer,
-                    const DvrNativeBufferMetadata* meta, int release_fence_fd);
-  void SetBufferAvailableCallback(
-      DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-  void SetBufferRemovedCallback(
-      DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-  int HandleEvents();
-
- private:
-  std::shared_ptr<ConsumerQueue> consumer_queue_;
-  std::array<std::unique_ptr<DvrReadBuffer>, BufferHubQueue::kMaxQueueCapacity>
-      read_buffers_;
-};
-
-#endif  // ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_configuration_data.cpp b/libs/vr/libdvr/dvr_configuration_data.cpp
deleted file mode 100644
index df0d54e..0000000
--- a/libs/vr/libdvr/dvr_configuration_data.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "include/dvr/dvr_configuration_data.h"
-
-#include <private/dvr/display_client.h>
-
-using android::dvr::display::ConfigFileType;
-using android::dvr::display::DisplayClient;
-
-extern "C" {
-
-int dvrConfigurationDataGet(int config_type, uint8_t** data,
-                            size_t* data_size) {
-  if (!data || !data_size) {
-    return -EINVAL;
-  }
-
-  auto client = DisplayClient::Create();
-  if (!client) {
-    ALOGE("dvrGetGlobalBuffer: Failed to create display client!");
-    return -ECOMM;
-  }
-
-  ConfigFileType config_file_type = static_cast<ConfigFileType>(config_type);
-  auto config_data_status =
-      client->GetConfigurationData(config_file_type);
-
-  if (!config_data_status) {
-    return -config_data_status.error();
-  }
-
-  *data_size = config_data_status.get().size();
-  *data = new uint8_t[*data_size];
-  std::copy_n(config_data_status.get().begin(), *data_size, *data);
-  return 0;
-}
-
-void dvrConfigurationDataDestroy(uint8_t* data) {
-  delete[] data;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp
deleted file mode 100644
index 7f631e3..0000000
--- a/libs/vr/libdvr/dvr_display_manager.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-#include "include/dvr/dvr_display_manager.h"
-
-#include <dvr/dvr_buffer.h>
-#include <pdx/rpc/variant.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/display_client.h>
-#include <private/dvr/display_manager_client.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerBuffer;
-using android::dvr::display::DisplayManagerClient;
-using android::dvr::display::SurfaceAttribute;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceState;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Extracts type and value from the attribute Variant and writes them into the
-// respective fields of DvrSurfaceAttribute.
-struct AttributeVisitor {
-  DvrSurfaceAttribute* attribute;
-
-  void operator()(int32_t value) {
-    attribute->value.int32_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
-  }
-  void operator()(int64_t value) {
-    attribute->value.int64_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
-  }
-  void operator()(bool value) {
-    attribute->value.bool_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
-  }
-  void operator()(float value) {
-    attribute->value.float_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
-  }
-  void operator()(const std::array<float, 2>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float2_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
-  }
-  void operator()(const std::array<float, 3>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float3_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
-  }
-  void operator()(const std::array<float, 4>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float4_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
-  }
-  void operator()(const std::array<float, 8>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float8_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
-  }
-  void operator()(const std::array<float, 16>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float16_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
-  }
-  void operator()(EmptyVariant) {
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  }
-};
-
-size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes,
-                                DvrSurfaceAttribute* attributes,
-                                size_t max_count) {
-  size_t count = 0;
-  for (const auto& attribute : surface_attributes) {
-    if (count >= max_count)
-      break;
-
-    // Copy the key and extract the Variant value using a visitor.
-    attributes[count].key = attribute.first;
-    attribute.second.Visit(AttributeVisitor{&attributes[count]});
-    count++;
-  }
-
-  return count;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-struct DvrDisplayManager {
-  std::unique_ptr<DisplayManagerClient> client;
-};
-
-struct DvrSurfaceState {
-  std::vector<SurfaceState> state;
-};
-
-int dvrDisplayManagerCreate(DvrDisplayManager** client_out) {
-  if (!client_out)
-    return -EINVAL;
-
-  auto client = DisplayManagerClient::Create();
-  if (!client) {
-    ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!");
-    return -EIO;
-  }
-
-  *client_out = new DvrDisplayManager{std::move(client)};
-  return 0;
-}
-
-void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; }
-
-int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) {
-  if (!client)
-    return -EINVAL;
-
-  return client->client->event_fd();
-}
-
-int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
-                                             int in_events, int* out_events) {
-  if (!client || !out_events)
-    return -EINVAL;
-
-  auto status = client->client->GetEventMask(in_events);
-  if (!status)
-    return -status.error();
-
-  *out_events = status.get();
-  return 0;
-}
-
-int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
-                                     DvrSurfaceState* state) {
-  if (!client || !state)
-    return -EINVAL;
-
-  auto status = client->client->GetSurfaceState();
-  if (!status)
-    return -status.error();
-
-  state->state = status.take();
-  return 0;
-}
-
-int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
-                                        int surface_id, int queue_id,
-                                        DvrReadBufferQueue** queue_out) {
-  if (!client || !queue_out)
-    return -EINVAL;
-
-  auto status = client->client->GetSurfaceQueue(surface_id, queue_id);
-  if (!status) {
-    ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *queue_out = new DvrReadBufferQueue(status.take());
-  return 0;
-}
-
-int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) {
-  if (!surface_state_out)
-    return -EINVAL;
-
-  *surface_state_out = new DvrSurfaceState{};
-  return 0;
-}
-
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) {
-  delete surface_state;
-}
-
-int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
-                                   size_t* count_out) {
-  if (!surface_state)
-    return -EINVAL;
-
-  *count_out = surface_state->state.size();
-  return 0;
-}
-
-int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
-                                  size_t surface_index,
-                                  DvrSurfaceUpdateFlags* flags_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *flags_out = surface_state->state[surface_index].update_flags;
-  return 0;
-}
-
-int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* surface_id_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *surface_id_out = surface_state->state[surface_index].surface_id;
-  return 0;
-}
-
-int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* process_id_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *process_id_out = surface_state->state[surface_index].process_id;
-  return 0;
-}
-
-int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
-                                 size_t surface_index, size_t* count_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *count_out = surface_state->state[surface_index].queue_ids.size();
-  return 0;
-}
-
-ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
-                                   size_t surface_index, int* queue_ids,
-                                   size_t max_count) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  size_t i;
-  const auto& state = surface_state->state[surface_index];
-  for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) {
-    queue_ids[i] = state.queue_ids[i];
-  }
-
-  return i;
-}
-
-int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
-                             size_t surface_index, int* z_order_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !z_order_out) {
-    return -EINVAL;
-  }
-
-  *z_order_out = surface_state->state[surface_index].GetZOrder();
-  return 0;
-}
-
-int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
-                              size_t surface_index, bool* visible_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !visible_out) {
-    return -EINVAL;
-  }
-
-  *visible_out = surface_state->state[surface_index].GetVisible();
-  return 0;
-}
-
-int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
-                                     size_t surface_index, size_t* count_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !count_out) {
-    return -EINVAL;
-  }
-
-  *count_out = surface_state->state[surface_index].surface_attributes.size();
-  return 0;
-}
-
-ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
-                                     size_t surface_index,
-                                     DvrSurfaceAttribute* attributes,
-                                     size_t max_count) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !attributes) {
-    return -EINVAL;
-  }
-
-  return ConvertSurfaceAttributes(
-      surface_state->state[surface_index].surface_attributes, attributes,
-      max_count);
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
deleted file mode 100644
index 4e87cf6..0000000
--- a/libs/vr/libdvr/dvr_hardware_composer_client.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "include/dvr/dvr_hardware_composer_client.h"
-
-#include <android/dvr/IVrComposer.h>
-#include <android/dvr/BnVrComposerCallback.h>
-#include <android/hardware_buffer.h>
-#include <binder/IServiceManager.h>
-#include <private/android/AHardwareBufferHelpers.h>
-
-#include <functional>
-#include <memory>
-#include <mutex>
-
-struct DvrHwcFrame {
-  android::dvr::ComposerView::Frame frame;
-};
-
-namespace {
-
-class HwcCallback : public android::dvr::BnVrComposerCallback {
- public:
-  using CallbackFunction = std::function<int(DvrHwcFrame*)>;
-
-  explicit HwcCallback(const CallbackFunction& callback);
-  ~HwcCallback() override;
-
-  // Reset the callback. This needs to be done early to avoid use after free
-  // accesses from binder thread callbacks.
-  void Shutdown();
-
-  std::unique_ptr<DvrHwcFrame> DequeueFrame();
-
- private:
-  // android::dvr::BnVrComposerCallback:
-  android::binder::Status onNewFrame(
-      const android::dvr::ParcelableComposerFrame& frame,
-      android::dvr::ParcelableUniqueFd* fence) override;
-
-  // Protects the |callback_| from uses from multiple threads. During shutdown
-  // there may be in-flight frame update events. In those cases the callback
-  // access needs to be protected otherwise binder threads may access an invalid
-  // callback.
-  std::mutex mutex_;
-  CallbackFunction callback_;
-
-  HwcCallback(const HwcCallback&) = delete;
-  void operator=(const HwcCallback&) = delete;
-};
-
-HwcCallback::HwcCallback(const CallbackFunction& callback)
-    : callback_(callback) {}
-
-HwcCallback::~HwcCallback() {}
-
-void HwcCallback::Shutdown() {
-  std::lock_guard<std::mutex> guard(mutex_);
-  callback_ = nullptr;
-}
-
-android::binder::Status HwcCallback::onNewFrame(
-    const android::dvr::ParcelableComposerFrame& frame,
-    android::dvr::ParcelableUniqueFd* fence) {
-  std::lock_guard<std::mutex> guard(mutex_);
-
-  if (!callback_) {
-    fence->set_fence(android::base::unique_fd());
-    return android::binder::Status::ok();
-  }
-
-  std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
-  dvr_frame->frame = frame.frame();
-
-  fence->set_fence(android::base::unique_fd(callback_(dvr_frame.release())));
-  return android::binder::Status::ok();
-}
-
-}  // namespace
-
-struct DvrHwcClient {
-  android::sp<android::dvr::IVrComposer> composer;
-  android::sp<HwcCallback> callback;
-};
-
-DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
-  std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
-
-  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
-  client->composer = android::interface_cast<android::dvr::IVrComposer>(
-      sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
-  if (!client->composer.get())
-    return nullptr;
-
-  client->callback = new HwcCallback(std::bind(callback, data,
-                                               std::placeholders::_1));
-  android::binder::Status status = client->composer->registerObserver(
-      client->callback);
-  if (!status.isOk())
-    return nullptr;
-
-  return client.release();
-}
-
-void dvrHwcClientDestroy(DvrHwcClient* client) {
-  client->composer->clearObserver();
-
-  // NOTE: Deleting DvrHwcClient* isn't enough since DvrHwcClient::callback is a
-  // shared pointer that could be referenced from a binder thread. But the
-  // client callback isn't valid past this calls so that needs to be reset.
-  client->callback->Shutdown();
-
-  delete client;
-}
-
-void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
-  delete frame;
-}
-
-DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
-  return frame->frame.display_id;
-}
-
-int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
-  return frame->frame.display_width;
-}
-
-int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
-  return frame->frame.display_height;
-}
-
-bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
-  return frame->frame.removed;
-}
-
-size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
-  return frame->frame.layers.size();
-}
-
-uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.active_config);
-}
-
-uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.color_mode);
-}
-
-void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
-                                  int32_t* out_hint) {
-  *out_hint = frame->frame.color_transform_hint;
-  memcpy(out_matrix, frame->frame.color_transform,
-         sizeof(frame->frame.color_transform));
-}
-
-uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.power_mode);
-}
-
-uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.vsync_enabled);
-}
-
-DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].id;
-}
-
-AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
-                                           size_t layer_index) {
-  AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
-      frame->frame.layers[layer_index].buffer.get());
-  AHardwareBuffer_acquire(buffer);
-  return buffer;
-}
-
-int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].fence->dup();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
-                                            size_t layer_index) {
-  return DvrHwcRecti{
-    frame->frame.layers[layer_index].display_frame.left,
-    frame->frame.layers[layer_index].display_frame.top,
-    frame->frame.layers[layer_index].display_frame.right,
-    frame->frame.layers[layer_index].display_frame.bottom,
-  };
-}
-
-DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
-  return DvrHwcRectf{
-    frame->frame.layers[layer_index].crop.left,
-    frame->frame.layers[layer_index].crop.top,
-    frame->frame.layers[layer_index].crop.right,
-    frame->frame.layers[layer_index].crop.bottom,
-  };
-}
-
-DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
-                                             size_t layer_index) {
-  return static_cast<DvrHwcBlendMode>(
-      frame->frame.layers[layer_index].blend_mode);
-}
-
-float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].alpha;
-}
-
-uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].type;
-}
-
-uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
-                                          size_t layer_index) {
-  return frame->frame.layers[layer_index].app_id;
-}
-
-uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].z_order;
-}
-
-void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
-                               int32_t* out_x, int32_t* out_y) {
-  *out_x = frame->frame.layers[layer_index].cursor_x;
-  *out_y = frame->frame.layers[layer_index].cursor_y;
-}
-
-uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].transform;
-}
-
-uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].dataspace;
-}
-
-uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
-  const auto& color = frame->frame.layers[layer_index].color;
-  return color.r | (static_cast<uint32_t>(color.g) << 8) |
-         (static_cast<uint32_t>(color.b) << 16) |
-         (static_cast<uint32_t>(color.a) << 24);
-}
-
-uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
-                                              size_t layer_index) {
-  return frame->frame.layers[layer_index].visible_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index) {
-  return DvrHwcRecti{
-      frame->frame.layers[layer_index].visible_regions[index].left,
-      frame->frame.layers[layer_index].visible_regions[index].top,
-      frame->frame.layers[layer_index].visible_regions[index].right,
-      frame->frame.layers[layer_index].visible_regions[index].bottom,
-  };
-}
-
-uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
-                                              size_t layer_index) {
-  return frame->frame.layers[layer_index].damaged_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index) {
-  return DvrHwcRecti{
-      frame->frame.layers[layer_index].damaged_regions[index].left,
-      frame->frame.layers[layer_index].damaged_regions[index].top,
-      frame->frame.layers[layer_index].damaged_regions[index].right,
-      frame->frame.layers[layer_index].damaged_regions[index].bottom,
-  };
-}
diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h
deleted file mode 100644
index f845cd8..0000000
--- a/libs/vr/libdvr/dvr_internal.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef ANDROID_DVR_INTERNAL_H_
-#define ANDROID_DVR_INTERNAL_H_
-
-#include <sys/cdefs.h>
-
-#include <memory>
-
-extern "C" {
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-
-}  // extern "C"
-
-namespace android {
-namespace dvr {
-
-class IonBuffer;
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
-    const std::shared_ptr<IonBuffer>& ion_buffer);
-
-}  // namespace dvr
-}  // namespace android
-
-extern "C" {
-
-struct DvrWriteBuffer {
-  // The slot nubmer of the buffer, a valid slot number must be in the range of
-  // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
-  // DvrWriteBuffer acquired from a DvrWriteBufferQueue.
-  int32_t slot = -1;
-
-  std::shared_ptr<android::dvr::ProducerBuffer> write_buffer;
-};
-
-struct DvrReadBuffer {
-  // The slot nubmer of the buffer, a valid slot number must be in the range of
-  // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
-  // DvrReadBuffer acquired from a DvrReadBufferQueue.
-  int32_t slot = -1;
-
-  std::shared_ptr<android::dvr::ConsumerBuffer> read_buffer;
-};
-
-struct DvrBuffer {
-  std::shared_ptr<android::dvr::IonBuffer> buffer;
-};
-
-}  // extern "C"
-
-#endif  // ANDROID_DVR_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_performance.cpp b/libs/vr/libdvr/dvr_performance.cpp
deleted file mode 100644
index 599101f..0000000
--- a/libs/vr/libdvr/dvr_performance.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "include/dvr/dvr_performance.h"
-
-#include <private/dvr/performance_client.h>
-
-using android::dvr::PerformanceClient;
-
-extern "C" {
-
-int dvrPerformanceSetSchedulerPolicy(pid_t task_id,
-                                     const char* scheduler_policy) {
-  int error;
-  if (auto client = PerformanceClient::Create(&error))
-    return client->SetSchedulerPolicy(task_id, scheduler_policy);
-  else
-    return error;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_pose.cpp b/libs/vr/libdvr/dvr_pose.cpp
deleted file mode 100644
index c379ef5..0000000
--- a/libs/vr/libdvr/dvr_pose.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "include/dvr/dvr_pose.h"
-
-#include <memory>
-
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/pose_client_internal.h>
-
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerQueue;
-
-int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type,
-                               DvrReadBufferQueue** queue_out) {
-  if (!client || !queue_out)
-    return -EINVAL;
-
-  ConsumerQueue* consumer_queue;
-  int status = android::dvr::dvrPoseClientGetDataReaderHandle(client,
-                                                              data_type,
-                                                              &consumer_queue);
-  if (status != 0) {
-    ALOGE("dvrPoseClientGetDataReader: Failed to get queue: %d", status);
-    return status;
-  }
-
-  std::shared_ptr<ConsumerQueue> consumer_queue_ptr{consumer_queue};
-  *queue_out = new DvrReadBufferQueue(consumer_queue_ptr);
-  return 0;
-}
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
deleted file mode 100644
index 0c7ec01..0000000
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-#include "include/dvr/dvr_surface.h"
-
-#include <inttypes.h>
-
-#include <pdx/rpc/variant.h>
-#include <private/android/AHardwareBufferHelpers.h>
-#include <private/dvr/display_client.h>
-
-#include "dvr_buffer_queue_internal.h"
-#include "dvr_internal.h"
-
-using android::AHardwareBuffer_convertToGrallocUsageBits;
-using android::dvr::display::DisplayClient;
-using android::dvr::display::Surface;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceAttributeValue;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Sets the Variant |destination| to the target std::array type and copies the C
-// array into it. Unsupported std::array configurations will fail to compile.
-template <typename T, std::size_t N>
-void ArrayCopy(SurfaceAttributeValue* destination, const T (&source)[N]) {
-  using ArrayType = std::array<T, N>;
-  *destination = ArrayType{};
-  std::copy(std::begin(source), std::end(source),
-            std::get<ArrayType>(*destination).begin());
-}
-
-bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
-                              size_t attribute_count,
-                              SurfaceAttributes* surface_attributes,
-                              size_t* error_index) {
-  for (size_t i = 0; i < attribute_count; i++) {
-    SurfaceAttributeValue value;
-    switch (attributes[i].value.type) {
-      case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
-        value = attributes[i].value.int32_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
-        value = attributes[i].value.int64_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
-        // bool_value is defined in an extern "C" block, which makes it look
-        // like an int to C++. Use a cast to assign the correct type to the
-        // Variant type SurfaceAttributeValue.
-        value = static_cast<bool>(attributes[i].value.bool_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
-        value = attributes[i].value.float_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
-        ArrayCopy(&value, attributes[i].value.float2_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
-        ArrayCopy(&value, attributes[i].value.float3_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
-        ArrayCopy(&value, attributes[i].value.float4_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
-        ArrayCopy(&value, attributes[i].value.float8_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
-        ArrayCopy(&value, attributes[i].value.float16_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_NONE:
-        value = EmptyVariant{};
-        break;
-      default:
-        *error_index = i;
-        return false;
-    }
-
-    surface_attributes->emplace(attributes[i].key, value);
-  }
-
-  return true;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-struct DvrSurface {
-  std::unique_ptr<Surface> surface;
-};
-
-int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
-                     size_t attribute_count, DvrSurface** out_surface) {
-  if (out_surface == nullptr) {
-    ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
-    return -EINVAL;
-  }
-
-  size_t error_index;
-  SurfaceAttributes surface_attributes;
-  if (!ConvertSurfaceAttributes(attributes, attribute_count,
-                                &surface_attributes, &error_index)) {
-    ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
-          attributes[error_index].value.type);
-    return -EINVAL;
-  }
-
-  auto status = Surface::CreateSurface(surface_attributes);
-  if (!status) {
-    ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *out_surface = new DvrSurface{status.take()};
-  return 0;
-}
-
-void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
-
-int dvrSurfaceGetId(DvrSurface* surface) {
-  return surface->surface->surface_id();
-}
-
-int dvrSurfaceSetAttributes(DvrSurface* surface,
-                            const DvrSurfaceAttribute* attributes,
-                            size_t attribute_count) {
-  if (surface == nullptr || attributes == nullptr) {
-    ALOGE(
-        "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
-        "attribute_count=%zu",
-        surface, attributes, attribute_count);
-    return -EINVAL;
-  }
-
-  size_t error_index;
-  SurfaceAttributes surface_attributes;
-  if (!ConvertSurfaceAttributes(attributes, attribute_count,
-                                &surface_attributes, &error_index)) {
-    ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
-          attributes[error_index].value.type);
-    return -EINVAL;
-  }
-
-  auto status = surface->surface->SetAttributes(surface_attributes);
-  if (!status) {
-    ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  return 0;
-}
-
-int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
-                                     uint32_t height, uint32_t format,
-                                     uint32_t layer_count, uint64_t usage,
-                                     size_t capacity, size_t metadata_size,
-                                     DvrWriteBufferQueue** out_writer) {
-  if (surface == nullptr || out_writer == nullptr) {
-    ALOGE(
-        "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
-        "out_writer=%p.",
-        surface, out_writer);
-    return -EINVAL;
-  }
-
-  auto status = surface->surface->CreateQueue(
-      width, height, layer_count, format, usage, capacity, metadata_size);
-  if (!status) {
-    ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *out_writer = new DvrWriteBufferQueue(status.take());
-  return 0;
-}
-
-int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
-                         DvrBuffer** buffer_out) {
-  if (!buffer_out)
-    return -EINVAL;
-
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
-
-  auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
-  if (!buffer_status) {
-    ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
-          buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
-  return 0;
-}
-
-int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  auto buffer_status = client->DeleteGlobalBuffer(key);
-  if (!buffer_status) {
-    ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
-          buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  return 0;
-}
-
-int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
-  if (!out_buffer)
-    return -EINVAL;
-
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  auto status = client->GetGlobalBuffer(key);
-  if (!status) {
-    return -status.error();
-  }
-  *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
-  return 0;
-}
-
-int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
-                               DvrNativeDisplayMetrics* metrics) {
-  ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
-           "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
-           "header is out of date.");
-
-  auto client = DisplayClient::Create();
-  if (!client) {
-    ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
-    return -ECOMM;
-  }
-
-  if (metrics == nullptr) {
-    ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
-    return -EINVAL;
-  }
-
-  auto status = client->GetDisplayMetrics();
-
-  if (!status) {
-    return -status.error();
-  }
-
-  if (sizeof_metrics >= 20) {
-    metrics->display_width = status.get().display_width;
-    metrics->display_height = status.get().display_height;
-    metrics->display_x_dpi = status.get().display_x_dpi;
-    metrics->display_y_dpi = status.get().display_y_dpi;
-    metrics->vsync_period_ns = status.get().vsync_period_ns;
-  }
-
-  return 0;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_tracking.cpp b/libs/vr/libdvr/dvr_tracking.cpp
deleted file mode 100644
index 73addc9..0000000
--- a/libs/vr/libdvr/dvr_tracking.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "include/dvr/dvr_tracking.h"
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#if !DVR_TRACKING_IMPLEMENTED
-
-extern "C" {
-
-// This file provides the stub implementation of dvrTrackingXXX APIs. On
-// platforms that implement these APIs, set -DDVR_TRACKING_IMPLEMENTED=1 in the
-// build file.
-int dvrTrackingCameraCreate(DvrTrackingCamera**) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingCameraDestroy(DvrTrackingCamera*) {
-  ALOGE("dvrTrackingCameraDestroy is not implemented.");
-}
-
-int dvrTrackingCameraStart(DvrTrackingCamera*, DvrWriteBufferQueue*) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingCameraStop(DvrTrackingCamera*) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorCreate(DvrTrackingFeatureExtractor**) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor*) {
-  ALOGE("dvrTrackingFeatureExtractorDestroy is not implemented.");
-}
-
-int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor*,
-                                     DvrTrackingFeatureCallback, void*) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor*) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorProcessBuffer(DvrTrackingFeatureExtractor*,
-                                             DvrReadBuffer*,
-                                             const DvrTrackingBufferMetadata*,
-                                             bool*) {
-  ALOGE("dvrTrackingFeatureExtractorProcessBuffer is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingSensorsCreate(DvrTrackingSensors**, const char*) {
-  ALOGE("dvrTrackingSensorsCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingSensorsDestroy(DvrTrackingSensors*) {
-  ALOGE("dvrTrackingSensorsDestroy is not implemented.");
-}
-
-int dvrTrackingSensorsStart(DvrTrackingSensors*, DvrTrackingSensorEventCallback,
-                            void*) {
-  ALOGE("dvrTrackingStart is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingSensorsStop(DvrTrackingSensors*) {
-  ALOGE("dvrTrackingStop is not implemented.");
-  return -ENOSYS;
-}
-
-}  // extern "C"
-
-#endif  // DVR_TRACKING_IMPLEMENTED
diff --git a/libs/vr/libdvr/exported_apis.lds b/libs/vr/libdvr/exported_apis.lds
deleted file mode 100644
index 5ecb498..0000000
--- a/libs/vr/libdvr/exported_apis.lds
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  global:
-    # Whitelist the function to load the dvr api.
-    dvrGetApi;
-
-  local:
-    # Hide everything else.
-    *;
-};
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
deleted file mode 100644
index fe7feb8..0000000
--- a/libs/vr/libdvr/tests/Android.bp
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (C) 2017 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_native_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_test {
-    srcs: [
-        "dvr_display_manager-test.cpp",
-        "dvr_named_buffer-test.cpp",
-        "dvr_tracking-test.cpp",
-    ],
-
-    header_libs: ["libdvr_headers"],
-    static_libs: [
-        "libdvr_static.google",
-        "libchrome",
-        "libdvrcommon",
-        "libdisplay",
-        "libbroadcastring",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libbufferhubqueue",
-        "libcutils",
-        "libgui",
-        "liblog",
-        "libhardware",
-        "libui",
-        "libutils",
-        "libnativewindow",
-        "libpdx_default_transport",
-    ],
-    cflags: [
-        "-DDVR_TRACKING_IMPLEMENTED=0",
-        "-DLOG_TAG=\"dvr_api-test\"",
-        "-DTRACE=0",
-        "-Wno-missing-field-initializers",
-        "-O0",
-        "-g",
-    ],
-    name: "dvr_api-test",
-}
-
-cc_test {
-    name: "dvr_buffer_queue-test",
-
-    // Includes the dvr_api.h header. Tests should only include "dvr_api.h",
-    // and shall only get access to |dvrGetApi|, as other symbols are hidden
-    // from the library.
-    include_dirs: ["frameworks/native/libs/vr/libdvr/include"],
-
-    srcs: ["dvr_buffer_queue-test.cpp"],
-
-    shared_libs: [
-        "libandroid",
-        "liblog",
-    ],
-
-    cflags: [
-        "-DTRACE=0",
-        "-O2",
-        "-g",
-    ],
-
-    // DTS Should only link to NDK libraries.
-    sdk_version: "26",
-    stl: "c++_static",
-}
-
-cc_test {
-    name: "dvr_display-test",
-
-    include_dirs: [
-        "frameworks/native/libs/vr/libdvr/include",
-        "frameworks/native/libs/nativewindow/include",
-    ],
-
-    srcs: ["dvr_display-test.cpp"],
-
-    shared_libs: [
-        "libandroid",
-        "liblog",
-    ],
-
-    cflags: [
-        "-DTRACE=0",
-        "-O2",
-        "-g",
-    ],
-
-    // DTS Should only link to NDK libraries.
-    sdk_version: "26",
-    stl: "c++_static",
-}
diff --git a/libs/vr/libdvr/tests/dvr_api_test.h b/libs/vr/libdvr/tests/dvr_api_test.h
deleted file mode 100644
index 5d2ec28..0000000
--- a/libs/vr/libdvr/tests/dvr_api_test.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <dlfcn.h>
-#include <dvr/dvr_api.h>
-
-#include <gtest/gtest.h>
-
-/** DvrTestBase loads the libdvr.so at runtime and get the Dvr API version 1. */
-class DvrApiTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    int flags = RTLD_NOW | RTLD_LOCAL;
-
-    // Here we need to ensure that libdvr is loaded with RTLD_NODELETE flag set
-    // (so that calls to `dlclose` don't actually unload the library). This is a
-    // workaround for an Android NDK bug. See more detail:
-    // https://github.com/android-ndk/ndk/issues/360
-    flags |= RTLD_NODELETE;
-    platform_handle_ = dlopen("libdvr.google.so", flags);
-    ASSERT_NE(nullptr, platform_handle_) << "Dvr shared library missing.";
-
-    auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>(
-        dlsym(platform_handle_, "dvrGetApi"));
-    ASSERT_NE(nullptr, dvr_get_api) << "Platform library missing dvrGetApi.";
-
-    ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0)
-        << "Unable to find compatible Dvr API.";
-  }
-
-  void TearDown() override {
-    if (platform_handle_ != nullptr) {
-      dlclose(platform_handle_);
-    }
-  }
-
-  void* platform_handle_ = nullptr;
-  DvrApi_v1 api_;
-};
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
deleted file mode 100644
index df06097..0000000
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-#include <android/log.h>
-#include <android/native_window.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_buffer_queue.h>
-
-#include <gtest/gtest.h>
-
-#include <array>
-#include <unordered_map>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_buffer_queue-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-#ifndef ALOGD_IF
-#define ALOGD_IF(cond, ...) \
-  ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
-#endif
-
-namespace {
-
-static constexpr uint32_t kBufferWidth = 100;
-static constexpr uint32_t kBufferHeight = 1;
-static constexpr uint32_t kLayerCount = 1;
-static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB;
-static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
-static constexpr size_t kQueueCapacity = 3;
-
-class DvrBufferQueueTest : public DvrApiTest {
- public:
-  static void BufferAvailableCallback(void* context) {
-    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
-    thiz->HandleBufferAvailable();
-  }
-
-  static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
-    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
-    thiz->HandleBufferRemoved(buffer);
-  }
-
- protected:
-  void TearDown() override {
-    if (write_queue_ != nullptr) {
-      api_.WriteBufferQueueDestroy(write_queue_);
-      write_queue_ = nullptr;
-    }
-    DvrApiTest::TearDown();
-  }
-
-  void HandleBufferAvailable() {
-    buffer_available_count_ += 1;
-    ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
-  }
-
-  void HandleBufferRemoved(DvrReadBuffer* buffer) {
-    buffer_removed_count_ += 1;
-    ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
-             buffer_removed_count_);
-  }
-
-  DvrWriteBufferQueue* write_queue_ = nullptr;
-  int buffer_available_count_{0};
-  int buffer_removed_count_{0};
-};
-
-TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  api_.WriteBufferQueueDestroy(write_queue_);
-  write_queue_ = nullptr;
-}
-
-TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  size_t capacity = api_.WriteBufferQueueGetCapacity(write_queue_);
-
-  ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue1 = nullptr;
-  DvrReadBufferQueue* read_queue2 = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue1);
-
-  ret = api_.ReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue2);
-  ASSERT_NE(read_queue1, read_queue2);
-
-  api_.ReadBufferQueueDestroy(read_queue1);
-  api_.ReadBufferQueueDestroy(read_queue2);
-}
-
-TEST_F(DvrBufferQueueTest, GainBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrWriteBuffer* wb = nullptr;
-  EXPECT_FALSE(api_.WriteBufferIsValid(wb));
-
-  DvrNativeBufferMetadata meta;
-  int fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
-                                        &fence_fd);
-  ASSERT_EQ(ret, 0);
-  EXPECT_EQ(fence_fd, -1);
-  EXPECT_NE(wb, nullptr);
-  EXPECT_TRUE(api_.WriteBufferIsValid(wb));
-}
-
-TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrReadBuffer* rb = nullptr;
-  DvrWriteBuffer* wb = nullptr;
-  DvrNativeBufferMetadata meta1;
-  DvrNativeBufferMetadata meta2;
-  int fence_fd = -1;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(read_queue, nullptr);
-
-  api_.ReadBufferQueueSetBufferAvailableCallback(
-      read_queue, &BufferAvailableCallback, this);
-
-  // Gain buffer for writing.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
-                                        &meta1, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(wb, nullptr);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb));
-  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
-           wb, fence_fd);
-  close(fence_fd);
-
-  // Post buffer to the read_queue.
-  meta1.timestamp = 42;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
-  ASSERT_EQ(ret, 0);
-  ASSERT_FALSE(api_.WriteBufferIsValid(wb));
-  wb = nullptr;
-
-  // Acquire buffer for reading.
-  ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
-                                          &meta2, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(rb, nullptr);
-
-  // Dequeue is successfully, BufferAvailableCallback should be fired once.
-  ASSERT_EQ(buffer_available_count_, 1);
-  ASSERT_TRUE(api_.ReadBufferIsValid(rb));
-
-  // Metadata should be passed along from producer to consumer properly.
-  ASSERT_EQ(meta1.timestamp, meta2.timestamp);
-
-  ALOGD_IF(TRACE,
-           "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
-           fence_fd);
-  close(fence_fd);
-
-  // Release buffer to the write_queue.
-  ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
-                                          /*release_fence_fd=*/-1);
-  ASSERT_EQ(ret, 0);
-  ASSERT_FALSE(api_.ReadBufferIsValid(rb));
-  rb = nullptr;
-
-  // TODO(b/34387835) Currently buffer allocation has to happen after all queues
-  // are initialized.
-  size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
-
-  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, GetANativeWindow) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, /*user_metadata_size=*/0, &write_queue_);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, write_queue_);
-
-  ANativeWindow* window = nullptr;
-  ret = api_.WriteBufferQueueGetANativeWindow(write_queue_, &window);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, window);
-
-  uint32_t width = ANativeWindow_getWidth(window);
-  uint32_t height = ANativeWindow_getHeight(window);
-  uint32_t format = ANativeWindow_getFormat(window);
-  ASSERT_EQ(kBufferWidth, width);
-  ASSERT_EQ(kBufferHeight, height);
-  ASSERT_EQ(kBufferFormat, format);
-}
-
-// Create buffer queue of three buffers and dequeue three buffers out of it.
-// Before each dequeue operation, we resize the buffer queue and expect the
-// queue always return buffer with desired dimension.
-TEST_F(DvrBufferQueueTest, ResizeBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  int fence_fd = -1;
-
-  DvrNativeBufferMetadata meta;
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrWriteBuffer* wb1 = nullptr;
-  DvrWriteBuffer* wb2 = nullptr;
-  DvrWriteBuffer* wb3 = nullptr;
-  AHardwareBuffer* ahb1 = nullptr;
-  AHardwareBuffer* ahb2 = nullptr;
-  AHardwareBuffer* ahb3 = nullptr;
-  AHardwareBuffer_Desc buffer_desc;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  api_.ReadBufferQueueSetBufferRemovedCallback(read_queue,
-                                               &BufferRemovedCallback, this);
-
-  // Handle all pending events on the read queue.
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-
-  size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
-  ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-
-  // Resize before dequeuing.
-  constexpr uint32_t w1 = 10;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // Gain first buffer for writing. All buffers will be resized.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb1));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
-  close(fence_fd);
-
-  // Check the buffer dimension.
-  ret = api_.WriteBufferGetAHardwareBuffer(wb1, &ahb1);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb1, &buffer_desc);
-  ASSERT_EQ(w1, buffer_desc.width);
-  ASSERT_EQ(kBufferHeight, buffer_desc.height);
-  AHardwareBuffer_release(ahb1);
-
-  // For the first resize, all buffers are reallocated.
-  int expected_buffer_removed_count = kQueueCapacity;
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  // Resize the queue. We are testing with blob format, keep height to be 1.
-  constexpr uint32_t w2 = 20;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // The next buffer we dequeued should have new width.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb2));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
-           fence_fd);
-  close(fence_fd);
-
-  // Check the buffer dimension, should be new width
-  ret = api_.WriteBufferGetAHardwareBuffer(wb2, &ahb2);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb2, &buffer_desc);
-  ASSERT_EQ(w2, buffer_desc.width);
-  AHardwareBuffer_release(ahb2);
-
-  // For the second resize, all but one buffers are reallocated.
-  expected_buffer_removed_count += (kQueueCapacity - 1);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  // Resize the queue for the third time.
-  constexpr uint32_t w3 = 30;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // The next buffer we dequeued should have new width.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb3));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
-           fence_fd);
-  close(fence_fd);
-
-  // Check the buffer dimension, should be new width
-  ret = api_.WriteBufferGetAHardwareBuffer(wb3, &ahb3);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb3, &buffer_desc);
-  ASSERT_EQ(w3, buffer_desc.width);
-  AHardwareBuffer_release(ahb3);
-
-  // For the third resize, all but two buffers are reallocated.
-  expected_buffer_removed_count += (kQueueCapacity - 2);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  int event_fd = api_.ReadBufferQueueGetEventFd(read_queue);
-  ASSERT_GT(event_fd, 0);
-}
-
-// Verifies a Dvr{Read,Write}BufferQueue contains the same set of
-// Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
-// the corresponding AHardwareBuffer handle stays the same.
-TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  int fence_fd = -1;
-  DvrReadBufferQueue* read_queue = nullptr;
-  EXPECT_EQ(0, api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
-
-  // Read buffers.
-  std::array<DvrReadBuffer*, kQueueCapacity> rbs;
-  // Write buffers.
-  std::array<DvrWriteBuffer*, kQueueCapacity> wbs;
-  // Buffer metadata.
-  std::array<DvrNativeBufferMetadata, kQueueCapacity> metas;
-  // Hardware buffers for Read buffers.
-  std::unordered_map<int, AHardwareBuffer*> rhbs;
-  // Hardware buffers for Write buffers.
-  std::unordered_map<int, AHardwareBuffer*> whbs;
-
-  constexpr int kNumTests = 100;
-
-  // This test runs the following operations many many times. Thus we prefer to
-  // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
-  std::function<void(size_t i)> Gain = [&](size_t i) {
-    int ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
-                                              &wbs[i], &metas[i], &fence_fd);
-    ASSERT_EQ(ret, 0);
-    ASSERT_LT(fence_fd, 0);  // expect invalid fence.
-    ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
-    int buffer_id = api_.WriteBufferGetId(wbs[i]);
-    ASSERT_GT(buffer_id, 0);
-
-    AHardwareBuffer* hb = nullptr;
-    ASSERT_EQ(0, api_.WriteBufferGetAHardwareBuffer(wbs[i], &hb));
-
-    auto whb_it = whbs.find(buffer_id);
-    if (whb_it == whbs.end()) {
-      // If this is a new buffer id, check that total number of unique
-      // hardware buffers won't exceed queue capacity.
-      ASSERT_LT(whbs.size(), kQueueCapacity);
-      whbs.emplace(buffer_id, hb);
-    } else {
-      // If this is a buffer id we have seen before, check that the
-      // buffer_id maps to the same AHardwareBuffer handle.
-      ASSERT_EQ(hb, whb_it->second);
-    }
-  };
-
-  std::function<void(size_t i)> Post = [&](size_t i) {
-    ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
-
-    metas[i].timestamp++;
-    int ret = api_.WriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
-                                              /*fence=*/-1);
-    ASSERT_EQ(ret, 0);
-  };
-
-  std::function<void(size_t i)> Acquire = [&](size_t i) {
-    int ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
-                                                &rbs[i], &metas[i], &fence_fd);
-    ASSERT_EQ(ret, 0);
-    ASSERT_LT(fence_fd, 0);  // expect invalid fence.
-    ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
-    int buffer_id = api_.ReadBufferGetId(rbs[i]);
-    ASSERT_GT(buffer_id, 0);
-
-    AHardwareBuffer* hb = nullptr;
-    ASSERT_EQ(0, api_.ReadBufferGetAHardwareBuffer(rbs[i], &hb));
-
-    auto rhb_it = rhbs.find(buffer_id);
-    if (rhb_it == rhbs.end()) {
-      // If this is a new buffer id, check that total number of unique hardware
-      // buffers won't exceed queue capacity.
-      ASSERT_LT(rhbs.size(), kQueueCapacity);
-      rhbs.emplace(buffer_id, hb);
-    } else {
-      // If this is a buffer id we have seen before, check that the buffer_id
-      // maps to the same AHardwareBuffer handle.
-      ASSERT_EQ(hb, rhb_it->second);
-    }
-  };
-
-  std::function<void(size_t i)> Release = [&](size_t i) {
-    ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
-    int ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
-                                                /*release_fence_fd=*/-1);
-    ASSERT_EQ(ret, 0);
-  };
-
-  // Scenario one:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-    }
-    // Post all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Post(i));
-    }
-    // Acquire all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-    }
-    // Release all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Release(i));
-    }
-  }
-
-  // Scenario two:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain and post all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-      ASSERT_NO_FATAL_FAILURE(Post(i));
-    }
-    // Acquire and release all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-      ASSERT_NO_FATAL_FAILURE(Release(i));
-    }
-  }
-
-  // Scenario three:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain all write buffers then post them in reversed order.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-    }
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i));
-    }
-
-    // Acquire all write buffers then release them in reversed order.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-    }
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i));
-    }
-  }
-}
-
-TEST_F(DvrBufferQueueTest, ConsumerReleaseAfterProducerDestroy) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrReadBuffer* rb = nullptr;
-  DvrWriteBuffer* wb = nullptr;
-  DvrNativeBufferMetadata meta1;
-  DvrNativeBufferMetadata meta2;
-  int fence_fd = -1;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-  ASSERT_EQ(ret, 0);
-
-  api_.ReadBufferQueueSetBufferAvailableCallback(
-      read_queue, &BufferAvailableCallback, this);
-
-  // Gain buffer for writing.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
-                                        &meta1, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  close(fence_fd);
-
-  // Post buffer to the read_queue.
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
-  ASSERT_EQ(ret, 0);
-  wb = nullptr;
-
-  // Acquire buffer for reading.
-  ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
-                                          &meta2, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  close(fence_fd);
-
-  // Destroy the write buffer queue and make sure the reader queue is picking
-  // these events up.
-  api_.WriteBufferQueueDestroy(write_queue_);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-
-  // Release buffer to the write_queue.
-  ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
-                                          /*release_fence_fd=*/-1);
-  ASSERT_EQ(ret, 0);
-  rb = nullptr;
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-}  // namespace
diff --git a/libs/vr/libdvr/tests/dvr_display-test.cpp b/libs/vr/libdvr/tests/dvr_display-test.cpp
deleted file mode 100644
index c72f940..0000000
--- a/libs/vr/libdvr/tests/dvr_display-test.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <android/log.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_display-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-class DvrDisplayTest : public DvrApiTest {
- protected:
-  void SetUp() override {
-    DvrApiTest::SetUp();
-    int ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics_),
-                                           &display_metrics_);
-    ASSERT_EQ(ret, 0) << "Failed to get display metrics.";
-    ALOGD(
-        "display_width: %d, display_height: %d, display_x_dpi: %d, "
-        "display_y_dpi: %d, vsync_period_ns: %d.",
-        display_metrics_.display_width, display_metrics_.display_height,
-        display_metrics_.display_x_dpi, display_metrics_.display_y_dpi,
-        display_metrics_.vsync_period_ns);
-  }
-
-  void TearDown() override {
-    if (write_queue_ != nullptr) {
-      api_.WriteBufferQueueDestroy(write_queue_);
-      write_queue_ = nullptr;
-    }
-    if (direct_surface_ != nullptr) {
-      api_.SurfaceDestroy(direct_surface_);
-      direct_surface_ = nullptr;
-    }
-    DvrApiTest::TearDown();
-  }
-
-  /* Convert a write buffer to an android hardware buffer and fill in
-   * color_textures evenly to the buffer.
-   * AssertionError if the width of the buffer is not equal to the input width,
-   * AssertionError if the height of the buffer is not equal to the input
-   * height.
-   */
-  void FillWriteBuffer(DvrWriteBuffer* write_buffer,
-                       const std::vector<uint32_t>& color_textures,
-                       uint32_t width, uint32_t height);
-
-  // Write buffer queue properties.
-  static constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
-                                     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
-                                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
-  static constexpr size_t kMetadataSize = 0;
-  static constexpr int kTimeoutMs = 1000;  // Time for getting buffer.
-  uint32_t kLayerCount = 1;
-  DvrWriteBufferQueue* write_queue_ = nullptr;
-  DvrSurface* direct_surface_ = nullptr;
-
-  // Device display properties.
-  DvrNativeDisplayMetrics display_metrics_;
-};
-
-TEST_F(DvrDisplayTest, DisplayWithOneBuffer) {
-  // Create a direct surface.
-  std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_attributes.data(),
-                         direct_surface_attributes.size(), &direct_surface_);
-  ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue with the direct surface.
-  constexpr size_t kCapacity = 1;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
-  // Get buffer from WriteBufferQueue.
-  DvrWriteBuffer* write_buffer = nullptr;
-  DvrNativeBufferMetadata out_meta;
-  int out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, kTimeoutMs, &write_buffer,
-                                        &out_meta, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  ASSERT_NE(nullptr, write_buffer) << "Gained buffer should not be null.";
-
-  // Color the write buffer.
-  FillWriteBuffer(write_buffer,
-                  {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
-                  width, height);
-
-  // Post buffer.
-  int ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
-                                        ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  sleep(5);  // For visual check on the device under test.
-  // Should observe three primary colors on the screen center.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithDoubleBuffering) {
-  // Create a direct surface.
-  std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_attributes.data(),
-                         direct_surface_attributes.size(), &direct_surface_);
-  ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue with the direct surface.
-  constexpr size_t kCapacity = 2;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
-  int num_display_cycles_in_5s = 5 / (display_metrics_.vsync_period_ns / 1e9);
-  ALOGD("The number of display cycles: %d", num_display_cycles_in_5s);
-  int bufferhub_id_prev_write_buffer = -1;
-  for (int i = 0; i < num_display_cycles_in_5s; ++i) {
-    // Get a buffer from the WriteBufferQueue.
-    DvrWriteBuffer* write_buffer = nullptr;
-    DvrNativeBufferMetadata out_meta;
-    int out_fence_fd = -1;
-    ret = api_.WriteBufferQueueGainBuffer(
-        write_queue_, kTimeoutMs, &write_buffer, &out_meta, &out_fence_fd);
-    EXPECT_EQ(0, ret) << "Failed to get the a write buffer.";
-    ASSERT_NE(nullptr, write_buffer) << "The gained buffer should not be null.";
-
-    int bufferhub_id = api_.WriteBufferGetId(write_buffer);
-    ALOGD("Display cycle: %d, bufferhub id of the write buffer: %d", i,
-          bufferhub_id);
-    EXPECT_NE(bufferhub_id_prev_write_buffer, bufferhub_id)
-        << "Double buffering should be using the two buffers in turns, not "
-           "reusing the same write buffer.";
-    bufferhub_id_prev_write_buffer = bufferhub_id;
-
-    // Color the write buffer.
-    if (i % 2) {
-      FillWriteBuffer(write_buffer, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
-                      height);
-    } else {
-      FillWriteBuffer(write_buffer, {0xff00ff00, 0xff0000ff, 0xffff0000}, width,
-                      height);
-    }
-
-    // Post the write buffer.
-    int ready_fence_fd = -1;
-    ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
-                                          ready_fence_fd);
-    EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-  }
-  // Should observe blinking screen in secondary colors
-  // although it is actually displaying primary colors.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithTwoHardwareLayers) {
-  // Create the direct_surface_0 of z order 10 and direct_surface_1 of z
-  // order 11.
-  DvrSurface* direct_surface_0 = nullptr;
-  std::vector<DvrSurfaceAttribute> direct_surface_0_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_0_attributes.data(),
-                         direct_surface_0_attributes.size(), &direct_surface_0);
-  EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  DvrSurface* direct_surface_1 = nullptr;
-  std::vector<DvrSurfaceAttribute> direct_surface_1_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 11},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  ret =
-      api_.SurfaceCreate(direct_surface_1_attributes.data(),
-                         direct_surface_1_attributes.size(), &direct_surface_1);
-  EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue for each of the direct surfaces.
-  constexpr size_t kCapacity = 1;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-
-  DvrWriteBufferQueue* write_queue_0 = nullptr;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_0, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_0);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  EXPECT_NE(nullptr, write_queue_0) << "Write buffer queue should not be null.";
-
-  DvrWriteBufferQueue* write_queue_1 = nullptr;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_1, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_1);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  EXPECT_NE(nullptr, write_queue_1) << "Write buffer queue should not be null.";
-
-  // Get a buffer from each of the write buffer queues.
-  DvrWriteBuffer* write_buffer_0 = nullptr;
-  DvrNativeBufferMetadata out_meta_0;
-  int out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(
-      write_queue_0, kTimeoutMs, &write_buffer_0, &out_meta_0, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  EXPECT_NE(nullptr, write_buffer_0) << "Gained buffer should not be null.";
-
-  DvrWriteBuffer* write_buffer_1 = nullptr;
-  DvrNativeBufferMetadata out_meta_1;
-  out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(
-      write_queue_1, kTimeoutMs, &write_buffer_1, &out_meta_1, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  EXPECT_NE(nullptr, write_buffer_1) << "Gained buffer should not be null.";
-
-  // Color the write buffers.
-  FillWriteBuffer(write_buffer_0, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
-                  height);
-  FillWriteBuffer(write_buffer_1, {0x7f00ff00, 0x7f0000ff, 0x7fff0000}, width,
-                  height);
-
-  // Post buffers.
-  int ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_0, write_buffer_0,
-                                        &out_meta_0, ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_1, write_buffer_1,
-                                        &out_meta_1, ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  sleep(5);  // For visual check on the device under test.
-  // Should observe three secondary colors.
-
-  // Test finished. Clean up buffers and surfaces.
-  if (write_queue_0 != nullptr) {
-    api_.WriteBufferQueueDestroy(write_queue_0);
-    write_queue_0 = nullptr;
-  }
-  if (write_queue_1 != nullptr) {
-    api_.WriteBufferQueueDestroy(write_queue_1);
-    write_queue_1 = nullptr;
-  }
-  if (direct_surface_0 != nullptr) {
-    api_.SurfaceDestroy(direct_surface_0);
-  }
-  if (direct_surface_1 != nullptr) {
-    api_.SurfaceDestroy(direct_surface_1);
-  }
-}
-
-void DvrDisplayTest::FillWriteBuffer(
-    DvrWriteBuffer* write_buffer, const std::vector<uint32_t>& color_textures,
-    uint32_t width, uint32_t height) {
-  uint32_t num_colors = color_textures.size();
-  // Convert the first write buffer to an android hardware buffer.
-  AHardwareBuffer* ah_buffer = nullptr;
-  int ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer);
-  ASSERT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer.";
-  ASSERT_NE(nullptr, ah_buffer) << "AHardware buffer should not be null.";
-  AHardwareBuffer_Desc ah_buffer_describe;
-  AHardwareBuffer_describe(ah_buffer, &ah_buffer_describe);
-  ASSERT_EQ(ah_buffer_describe.format, kFormat)
-      << "The format of the android hardware buffer is wrong.";
-  ASSERT_EQ(ah_buffer_describe.layers, kLayerCount)
-      << "The obtained android hardware buffer should have 2 layers.";
-  ASSERT_EQ(ah_buffer_describe.width, width)
-      << "The obtained android hardware buffer width is wrong.";
-  ASSERT_EQ(ah_buffer_describe.height, height)
-      << "The obtained android hardware buffer height is wrong.";
-  // Change the content of the android hardware buffer.
-  void* buffer_data = nullptr;
-  int32_t fence = -1;
-  ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
-                             fence, nullptr, &buffer_data);
-  ASSERT_EQ(0, ret) << "Failed to lock the hardware buffer.";
-  ASSERT_NE(nullptr, buffer_data) << "Buffer data should not be null.";
-
-  uint32_t num_pixels = width * height / num_colors;
-  for (uint32_t color_index = 0; color_index < num_colors - 1; ++color_index) {
-    uint32_t color_texture = color_textures[color_index];
-    for (uint32_t i = 0; i < num_pixels; ++i) {
-      memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
-                                     (i + num_pixels * color_index) *
-                                         sizeof(color_texture)),
-             &color_texture, sizeof(color_texture));
-    }
-  }
-  uint32_t color_texture = color_textures[num_colors - 1];
-  uint32_t num_colored_pixels = num_pixels * (num_colors - 1);
-  num_pixels = width * height - num_colored_pixels;
-  for (uint32_t i = 0; i < num_pixels; ++i) {
-    memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
-                                   (i + num_colored_pixels) *
-                                       sizeof(color_texture)),
-           &color_texture, sizeof(color_texture));
-  }
-  fence = -1;
-  ret = AHardwareBuffer_unlock(ah_buffer, &fence);
-  EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer.";
-
-  // Release the android hardware buffer.
-  AHardwareBuffer_release(ah_buffer);
-}
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
deleted file mode 100644
index 07e2121..0000000
--- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
+++ /dev/null
@@ -1,891 +0,0 @@
-#include <android-base/properties.h>
-#include <base/logging.h>
-#include <cutils/properties.h>
-#include <gtest/gtest.h>
-#include <log/log.h>
-#include <poll.h>
-
-#include <android/hardware_buffer.h>
-
-#include <algorithm>
-#include <array>
-#include <set>
-#include <thread>
-#include <vector>
-
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_deleter.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_surface.h>
-
-#include <pdx/status.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-using ::testing::Test;
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, nullptr_t) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int32_t value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
-  attribute.value.int32_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int64_t value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
-  attribute.value.int64_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, bool value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
-  attribute.value.bool_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, float value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
-  attribute.value.float_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 2>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
-  std::copy(value.begin(), value.end(), attribute.value.float2_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 3>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
-  std::copy(value.begin(), value.end(), attribute.value.float3_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 4>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
-  std::copy(value.begin(), value.end(), attribute.value.float4_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 8>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
-  std::copy(value.begin(), value.end(), attribute.value.float8_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 16>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
-  std::copy(value.begin(), value.end(), attribute.value.float16_value);
-  return attribute;
-}
-
-Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false,
-                                                  int32_t z_order = 0) {
-  DvrSurface* surface = nullptr;
-  DvrSurfaceAttribute attributes[] = {
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order),
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)};
-
-  const int ret = dvrSurfaceCreate(
-      attributes, std::extent<decltype(attributes)>::value, &surface);
-  if (ret < 0)
-    return ErrorStatus(-ret);
-  else
-    return {UniqueDvrSurface(surface)};
-}
-
-Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
-    const UniqueDvrSurface& surface, uint32_t width, uint32_t height,
-    uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity,
-    size_t metadata_size) {
-  DvrWriteBufferQueue* queue;
-  const int ret = dvrSurfaceCreateWriteBufferQueue(
-      surface.get(), width, height, format, layer_count, usage, capacity,
-      metadata_size, &queue);
-  if (ret < 0)
-    return ErrorStatus(-ret);
-  else
-    return {UniqueDvrWriteBufferQueue(queue)};
-}
-
-Status<std::vector<uint8_t>> GetConfigData(int config_type) {
-  uint8_t* data = nullptr;
-  size_t data_size = 0;
-  int error = dvrConfigurationDataGet(config_type, &data, &data_size);
-  if (error < 0) {
-    return ErrorStatus(-error);
-  }
-
-  if (!data || data_size == 0) {
-    return ErrorStatus(EINVAL);
-  }
-  std::vector<uint8_t> data_result(data, data + data_size);
-  dvrConfigurationDataDestroy(data);
-  std::string s(data, data + data_size);
-  return {std::move(data_result)};
-}
-
-class TestDisplayManager {
- public:
-  TestDisplayManager(UniqueDvrDisplayManager display_manager,
-                     UniqueDvrSurfaceState surface_state)
-      : display_manager_(std::move(display_manager)),
-        surface_state_(std::move(surface_state)) {
-    const int fd = dvrDisplayManagerGetEventFd(display_manager_.get());
-    LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd);
-    display_manager_event_fd_ = fd;
-  }
-
-  Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id,
-                                                      int queue_id) {
-    DvrReadBufferQueue* queue;
-    const int ret = dvrDisplayManagerGetReadBufferQueue(
-        display_manager_.get(), surface_id, queue_id, &queue);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {UniqueDvrReadBufferQueue(queue)};
-  }
-
-  Status<void> UpdateSurfaceState() {
-    const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(),
-                                                     surface_state_.get());
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {};
-  }
-
-  enum : int { kTimeoutMs = 10000 };  // 10s
-
-  Status<void> WaitForUpdate(int timeout_ms = kTimeoutMs) {
-    if (display_manager_event_fd_ < 0)
-      return ErrorStatus(-display_manager_event_fd_);
-
-    pollfd pfd = {display_manager_event_fd_, POLLIN, 0};
-    const int count = poll(&pfd, 1, timeout_ms);
-    if (count < 0)
-      return ErrorStatus(errno);
-    else if (count == 0)
-      return ErrorStatus(ETIMEDOUT);
-
-    int events;
-    const int ret = dvrDisplayManagerTranslateEpollEventMask(
-        display_manager_.get(), pfd.revents, &events);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else if (events & POLLIN)
-      return UpdateSurfaceState();
-    else
-      return ErrorStatus(EPROTO);
-  }
-
-  Status<size_t> GetSurfaceCount() {
-    size_t count = 0;
-    const int ret =
-        dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {count};
-  }
-
-  Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) {
-    DvrSurfaceUpdateFlags update_flags;
-    const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(),
-                                                  surface_index, &update_flags);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {update_flags};
-  }
-
-  Status<int> GetSurfaceId(size_t surface_index) {
-    int surface_id;
-    const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(),
-                                                surface_index, &surface_id);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {surface_id};
-  }
-
-  Status<int> GetProcessId(size_t surface_index) {
-    int process_id;
-    const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(),
-                                                surface_index, &process_id);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {process_id};
-  }
-
-  Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) {
-    std::vector<DvrSurfaceAttribute> attributes;
-    size_t count = 0;
-    const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(),
-                                                     surface_index, &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-
-    attributes.resize(count);
-    const ssize_t return_count = dvrSurfaceStateGetAttributes(
-        surface_state_.get(), surface_index, attributes.data(), count);
-    if (return_count < 0)
-      return ErrorStatus(-return_count);
-
-    attributes.resize(return_count);
-    return {std::move(attributes)};
-  }
-
-  Status<std::vector<int>> GetQueueIds(size_t surface_index) {
-    std::vector<int> queue_ids;
-    size_t count = 0;
-    const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(),
-                                                 surface_index, &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-
-    if (count > 0) {
-      queue_ids.resize(count);
-      const ssize_t return_count = dvrSurfaceStateGetQueueIds(
-          surface_state_.get(), surface_index, queue_ids.data(), count);
-      if (return_count < 0)
-        return ErrorStatus(-return_count);
-
-      queue_ids.resize(return_count);
-    }
-
-    return {std::move(queue_ids)};
-  }
-
- private:
-  UniqueDvrDisplayManager display_manager_;
-  UniqueDvrSurfaceState surface_state_;
-
-  // Owned by object in display_manager_, do not explicitly close.
-  int display_manager_event_fd_;
-
-  TestDisplayManager(const TestDisplayManager&) = delete;
-  void operator=(const TestDisplayManager&) = delete;
-};
-
-class DvrDisplayManagerTest : public Test {
- protected:
-  void SetUp() override {
-    int ret;
-    DvrDisplayManager* display_manager;
-    DvrSurfaceState* surface_state;
-
-    ret = dvrDisplayManagerCreate(&display_manager);
-    ASSERT_EQ(0, ret) << "Failed to create display manager client";
-    ASSERT_NE(nullptr, display_manager);
-
-    ret = dvrSurfaceStateCreate(&surface_state);
-    ASSERT_EQ(0, ret) << "Failed to create surface state object";
-    ASSERT_NE(nullptr, surface_state);
-
-    manager_.reset(
-        new TestDisplayManager(UniqueDvrDisplayManager(display_manager),
-                               UniqueDvrSurfaceState(surface_state)));
-  }
-  void TearDown() override {}
-
-  std::unique_ptr<TestDisplayManager> manager_;
-};
-
-// TODO(eieio): Consider moving these somewhere more central because they are
-// broadly useful.
-
-template <typename T>
-testing::AssertionResult StatusOk(const char* status_expression,
-                                  const Status<T>& status) {
-  if (!status.ok()) {
-    return testing::AssertionFailure()
-           << "(" << status_expression
-           << ") expected to indicate success but actually contains error ("
-           << status.error() << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T>
-testing::AssertionResult StatusError(const char* status_expression,
-                                     const Status<T>& status) {
-  if (status.ok()) {
-    return testing::AssertionFailure()
-           << "(" << status_expression
-           << ") expected to indicate error but instead indicates success.";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T>
-testing::AssertionResult StatusHasError(const char* status_expression,
-                                        const char* /*error_code_expression*/,
-                                        const Status<T>& status,
-                                        int error_code) {
-  if (status.ok()) {
-    return StatusError(status_expression, status);
-  } else if (status.error() != error_code) {
-    return testing::AssertionFailure()
-           << "(" << status_expression << ") expected to indicate error ("
-           << error_code << ") but actually indicates error (" << status.error()
-           << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T, typename U>
-testing::AssertionResult StatusHasValue(const char* status_expression,
-                                        const char* /*value_expression*/,
-                                        const Status<T>& status,
-                                        const U& value) {
-  if (!status.ok()) {
-    return StatusOk(status_expression, status);
-  } else if (status.get() != value) {
-    return testing::AssertionFailure()
-           << "(" << status_expression << ") expected to contain value ("
-           << testing::PrintToString(value) << ") but actually contains value ("
-           << testing::PrintToString(status.get()) << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T, typename Op>
-testing::AssertionResult StatusPred(const char* status_expression,
-                                    const char* pred_expression,
-                                    const Status<T>& status, Op pred) {
-  if (!status.ok()) {
-    return StatusOk(status_expression, status);
-  } else if (!pred(status.get())) {
-    return testing::AssertionFailure()
-           << status_expression << " value ("
-           << testing::PrintToString(status.get())
-           << ") failed to pass predicate " << pred_expression;
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-#define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status)
-#define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status)
-
-#define ASSERT_STATUS_ERROR_VALUE(value, status) \
-  ASSERT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define ASSERT_STATUS_EQ(value, status) \
-  ASSERT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status)
-#define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status)
-
-#define EXPECT_STATUS_ERROR_VALUE(value, status) \
-  EXPECT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define EXPECT_STATUS_EQ(value, status) \
-  EXPECT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_PRED(pred, status) \
-  EXPECT_PRED_FORMAT2(StatusPred, status, pred)
-
-#if 0
-// Verify utility predicate/macro functionality. This section is commented out
-// because it is designed to fail in some cases to validate the helpers.
-TEST_F(Test, ExpectVoid) {
-  Status<void> status_error{ErrorStatus{EINVAL}};
-  Status<void> status_ok{};
-
-  EXPECT_STATUS_ERROR(status_error);
-  EXPECT_STATUS_ERROR(status_ok);
-  EXPECT_STATUS_OK(status_error);
-  EXPECT_STATUS_OK(status_ok);
-
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-}
-
-TEST_F(Test, ExpectInt) {
-  Status<int> status_error{ErrorStatus{EINVAL}};
-  Status<int> status_ok{10};
-
-  EXPECT_STATUS_ERROR(status_error);
-  EXPECT_STATUS_ERROR(status_ok);
-  EXPECT_STATUS_OK(status_error);
-  EXPECT_STATUS_OK(status_ok);
-
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-
-  EXPECT_STATUS_EQ(10, status_error);
-  EXPECT_STATUS_EQ(20, status_error);
-  EXPECT_STATUS_EQ(10, status_ok);
-  EXPECT_STATUS_EQ(20, status_ok);
-
-  auto pred1 = [](const auto& value) { return value < 15; };
-  auto pred2 = [](const auto& value) { return value > 5; };
-  auto pred3 = [](const auto& value) { return value > 15; };
-  auto pred4 = [](const auto& value) { return value < 5; };
-
-  EXPECT_STATUS_PRED(pred1, status_error);
-  EXPECT_STATUS_PRED(pred2, status_error);
-  EXPECT_STATUS_PRED(pred3, status_error);
-  EXPECT_STATUS_PRED(pred4, status_error);
-  EXPECT_STATUS_PRED(pred1, status_ok);
-  EXPECT_STATUS_PRED(pred2, status_ok);
-  EXPECT_STATUS_PRED(pred3, status_ok);
-  EXPECT_STATUS_PRED(pred4, status_ok);
-}
-#endif
-
-TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) {
-  // Get surface state and verify there are no surfaces.
-  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
-  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
-  // Get flags for invalid surface index.
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0));
-
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  const int surface_id = dvrSurfaceGetId(surface.get());
-  ASSERT_GE(surface_id, 0);
-
-  // Now there should be one new surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify the new surface flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  // Verify the surface id matches.
-  EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0));
-
-  // Verify the owning process of the surface.
-  EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0));
-
-  surface.reset();
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) {
-  // Get surface state and verify there are no surfaces.
-  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
-  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
-  // Get attributes for an invalid surface index.
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0));
-
-  const bool kInitialVisibility = true;
-  const int32_t kInitialZOrder = 10;
-  auto surface_status =
-      CreateApplicationSurface(kInitialVisibility, kInitialZOrder);
-  ASSERT_STATUS_OK(surface_status);
-  auto surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Check the initial attribute values.
-  auto attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  auto attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  std::set<int32_t> actual_keys;
-  std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                                     DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  // Collect all the keys in attributes that match the expected keys.
-  auto compare_keys = [](const auto& attributes, const auto& expected_keys) {
-    std::set<int32_t> keys;
-    for (const auto& attribute : attributes) {
-      if (expected_keys.find(attribute.key) != expected_keys.end())
-        keys.emplace(attribute.key);
-    }
-    return keys;
-  };
-
-  // If the sets match then attributes contained at least the expected keys,
-  // even if other keys were also present.
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  std::vector<DvrSurfaceAttribute> attributes_to_set = {
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, 0)};
-
-  // Test invalid args.
-  EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(nullptr, attributes_to_set.data(),
-                                             attributes_to_set.size()));
-  EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(surface.get(), nullptr,
-                                             attributes_to_set.size()));
-
-  // Test attribute change events.
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-
-  // Verify the attributes changed flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                   DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  // Test setting and then deleting an attribute.
-  const DvrSurfaceAttributeKey kUserKey = 1;
-  attributes_to_set = {MakeAttribute(kUserKey, 1024)};
-
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
-                   kUserKey};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  // Delete the attribute.
-  attributes_to_set = {MakeAttribute(kUserKey, nullptr)};
-
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
-                   kUserKey};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_NE(expected_keys, actual_keys);
-
-  // Test deleting a reserved attribute.
-  attributes_to_set = {MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, nullptr)};
-
-  EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-
-  // Failed attribute operations should not trigger update events.
-  const int kTimeoutMs = 100;  // 0.1s
-  EXPECT_STATUS_ERROR_VALUE(ETIMEDOUT, manager_->WaitForUpdate(kTimeoutMs));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                   DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeTypes) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  enum : std::int32_t {
-    kInt32Key = 1,
-    kInt64Key,
-    kBoolKey,
-    kFloatKey,
-    kFloat2Key,
-    kFloat3Key,
-    kFloat4Key,
-    kFloat8Key,
-    kFloat16Key,
-  };
-
-  const std::vector<DvrSurfaceAttribute> attributes_to_set = {
-      MakeAttribute(kInt32Key, int32_t{0}),
-      MakeAttribute(kInt64Key, int64_t{0}),
-      MakeAttribute(kBoolKey, false),
-      MakeAttribute(kFloatKey, 0.0f),
-      MakeAttribute(kFloat2Key, std::array<float, 2>{{1.0f, 2.0f}}),
-      MakeAttribute(kFloat3Key, std::array<float, 3>{{3.0f, 4.0f, 5.0f}}),
-      MakeAttribute(kFloat4Key, std::array<float, 4>{{6.0f, 7.0f, 8.0f, 9.0f}}),
-      MakeAttribute(kFloat8Key,
-                    std::array<float, 8>{{10.0f, 11.0f, 12.0f, 13.0f, 14.0f,
-                                          15.0f, 16.0f, 17.0f}}),
-      MakeAttribute(kFloat16Key, std::array<float, 16>{
-                                     {18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f,
-                                      24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f,
-                                      30.0f, 31.0f, 32.0f, 33.0f}})};
-
-  EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  auto attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  auto attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), attributes_to_set.size());
-
-  auto HasAttribute = [](const auto& attributes,
-                         DvrSurfaceAttributeKey key) -> bool {
-    for (const auto& attribute : attributes) {
-      if (attribute.key == key)
-        return true;
-    }
-    return false;
-  };
-  auto AttributeType =
-      [](const auto& attributes,
-         DvrSurfaceAttributeKey key) -> DvrSurfaceAttributeType {
-    for (const auto& attribute : attributes) {
-      if (attribute.key == key)
-        return attribute.value.type;
-    }
-    return DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  };
-
-  ASSERT_TRUE(HasAttribute(attributes, kInt32Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-            AttributeType(attributes, kInt32Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kInt64Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT64,
-            AttributeType(attributes, kInt64Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kBoolKey));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-            AttributeType(attributes, kBoolKey));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloatKey));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT,
-            AttributeType(attributes, kFloatKey));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat2Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2,
-            AttributeType(attributes, kFloat2Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat3Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3,
-            AttributeType(attributes, kFloat3Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat4Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4,
-            AttributeType(attributes, kFloat4Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat8Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8,
-            AttributeType(attributes, kFloat8Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat16Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16,
-            AttributeType(attributes, kFloat16Key));
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  const int surface_id = dvrSurfaceGetId(surface.get());
-  ASSERT_GE(surface_id, 0);
-  // Get surface state and verify there is one surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify there are no queues for the surface recorded in the state
-  // snapshot.
-  EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0));
-
-  // Create a new queue in the surface.
-  auto write_queue_status = CreateSurfaceQueue(
-      surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1,
-      AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
-  ASSERT_STATUS_OK(write_queue_status);
-  UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
-  ASSERT_NE(nullptr, write_queue.get());
-
-  const int queue_id = dvrWriteBufferQueueGetId(write_queue.get());
-  ASSERT_GE(queue_id, 0);
-
-  // Update surface state.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify the buffers changed flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  auto queue_ids_status = manager_->GetQueueIds(0);
-  ASSERT_STATUS_OK(queue_ids_status);
-
-  auto queue_ids = queue_ids_status.take();
-  ASSERT_EQ(1u, queue_ids.size());
-  EXPECT_EQ(queue_id, queue_ids[0]);
-
-  auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id);
-  ASSERT_STATUS_OK(read_queue_status);
-  UniqueDvrReadBufferQueue read_queue = read_queue_status.take();
-  ASSERT_NE(nullptr, read_queue.get());
-  EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get()));
-
-  write_queue.reset();
-
-  // Verify that destroying the queue generates a surface update event.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify that the buffers changed flag is set.
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  // Verify that the queue ids reflect the change.
-  queue_ids_status = manager_->GetQueueIds(0);
-  ASSERT_STATUS_OK(queue_ids_status);
-
-  queue_ids = queue_ids_status.take();
-  ASSERT_EQ(0u, queue_ids.size());
-}
-
-TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  // Get surface state and verify there is one surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Create a new queue in the surface.
-  const uint32_t kLayerCount = 3;
-  auto write_queue_status = CreateSurfaceQueue(
-      surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount,
-      AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
-  ASSERT_STATUS_OK(write_queue_status);
-  UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
-  ASSERT_NE(nullptr, write_queue.get());
-
-  DvrWriteBuffer* buffer = nullptr;
-  DvrNativeBufferMetadata metadata;
-  int fence_fd = -1;
-  int error = dvrWriteBufferQueueGainBuffer(write_queue.get(), /*timeout=*/1000,
-                                            &buffer, &metadata, &fence_fd);
-  ASSERT_EQ(0, error);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer);
-  ASSERT_EQ(0, error);
-
-  AHardwareBuffer_Desc desc = {};
-  AHardwareBuffer_describe(hardware_buffer, &desc);
-  ASSERT_EQ(kLayerCount, desc.layers);
-
-  AHardwareBuffer_release(hardware_buffer);
-  dvrWriteBufferDestroy(buffer);
-}
-
-TEST_F(Test, ConfigurationData) {
-  // TODO(hendrikw): Move this test and GetConfigData helper function out of the
-  // display manager tests.
-  auto data1 = GetConfigData(-1);
-  ASSERT_STATUS_ERROR(data1);
-
-  const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
-
-  // This should be run on devices with and without built in metrics.
-  bool has_metric = !base::GetProperty(kDvrLensMetricsProperty, "").empty();
-  auto data2 = GetConfigData(DVR_CONFIGURATION_DATA_LENS_METRICS);
-  if (has_metric) {
-    ASSERT_STATUS_OK(data2);
-    ASSERT_NE(0u, data2.get().size());
-  } else {
-    ASSERT_STATUS_ERROR(data2);
-  }
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
deleted file mode 100644
index 5c837e7..0000000
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_config.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <dvr/dvr_surface.h>
-#include <system/graphics.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-TEST(DvrGlobalBufferTest, TestGlobalBuffersSameName) {
-  const DvrGlobalBufferKey buffer_key = 101;
-  DvrBuffer* buffer1 = nullptr;
-  int ret1 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer1);
-  ASSERT_EQ(0, ret1);
-  ASSERT_NE(nullptr, buffer1);
-
-  DvrBuffer* buffer2 = nullptr;
-  int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2);
-  ASSERT_EQ(0, ret2);
-  ASSERT_NE(nullptr, buffer2);
-
-  AHardwareBuffer* hardware_buffer1 = nullptr;
-  int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
-  ASSERT_EQ(0, e1);
-  ASSERT_NE(nullptr, hardware_buffer1);
-
-  AHardwareBuffer* hardware_buffer2 = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer2);
-
-  AHardwareBuffer_Desc desc1 = {};
-  AHardwareBuffer_describe(hardware_buffer1, &desc1);
-  AHardwareBuffer_Desc desc2 = {};
-  AHardwareBuffer_describe(hardware_buffer2, &desc2);
-  ASSERT_EQ(desc1.width, 10u);
-  ASSERT_EQ(desc1.height, 1u);
-  ASSERT_EQ(desc1.layers, 1u);
-  ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc1.usage, 0u);
-  ASSERT_EQ(desc2.width, 10u);
-  ASSERT_EQ(desc2.height, 1u);
-  ASSERT_EQ(desc2.layers, 1u);
-  ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc2.usage, 0u);
-
-  dvrBufferDestroy(buffer1);
-  dvrBufferDestroy(buffer2);
-
-  DvrBuffer* buffer3 = nullptr;
-  int e3 = dvrGetGlobalBuffer(buffer_key, &buffer3);
-  ASSERT_NE(nullptr, buffer3);
-  ASSERT_EQ(0, e3);
-
-  AHardwareBuffer* hardware_buffer3 = nullptr;
-  int e4 = dvrBufferGetAHardwareBuffer(buffer3, &hardware_buffer3);
-  ASSERT_EQ(0, e4);
-  ASSERT_NE(nullptr, hardware_buffer3);
-
-  AHardwareBuffer_Desc desc3 = {};
-  AHardwareBuffer_describe(hardware_buffer3, &desc3);
-  ASSERT_EQ(desc3.width, 10u);
-  ASSERT_EQ(desc3.height, 1u);
-  ASSERT_EQ(desc3.layers, 1u);
-  ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc3.usage, 0u);
-
-  dvrBufferDestroy(buffer3);
-
-  AHardwareBuffer_release(hardware_buffer1);
-  AHardwareBuffer_release(hardware_buffer2);
-  AHardwareBuffer_release(hardware_buffer3);
-}
-
-TEST(DvrGlobalBufferTest, TestMultipleGlobalBuffers) {
-  const DvrGlobalBufferKey buffer_key1 = 102;
-  const DvrGlobalBufferKey buffer_key2 = 103;
-  DvrBuffer* setup_buffer1 = nullptr;
-  int ret1 = dvrSetupGlobalBuffer(buffer_key1, 10, 0, &setup_buffer1);
-  ASSERT_EQ(0, ret1);
-  ASSERT_NE(nullptr, setup_buffer1);
-  dvrBufferDestroy(setup_buffer1);
-
-  DvrBuffer* setup_buffer2 = nullptr;
-  int ret2 = dvrSetupGlobalBuffer(buffer_key2, 10, 0, &setup_buffer2);
-  ASSERT_EQ(0, ret2);
-  ASSERT_NE(nullptr, setup_buffer2);
-  dvrBufferDestroy(setup_buffer2);
-
-  DvrBuffer* buffer1 = nullptr;
-  int e1 = dvrGetGlobalBuffer(buffer_key1, &buffer1);
-  ASSERT_NE(nullptr, buffer1);
-  ASSERT_EQ(0, e1);
-  dvrBufferDestroy(buffer1);
-
-  DvrBuffer* buffer2 = nullptr;
-  int e2 = dvrGetGlobalBuffer(buffer_key2, &buffer2);
-  ASSERT_NE(nullptr, buffer2);
-  ASSERT_EQ(0, e2);
-  dvrBufferDestroy(buffer2);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferUsage) {
-  const DvrGlobalBufferKey buffer_key = 100;
-
-  // Set usage to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE. We use this because
-  // internally AHARDWAREBUFFER_USAGE_VIDEO_ENCODE is converted to
-  // GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, and these two values are different.
-  // If all is good, when we get the AHardwareBuffer, it should be converted
-  // back to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE.
-  const uint64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE;
-
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_key, 10, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e1);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer);
-
-  AHardwareBuffer_Desc desc = {};
-  AHardwareBuffer_describe(hardware_buffer, &desc);
-  ASSERT_EQ(usage, desc.usage);
-
-  dvrBufferDestroy(setup_buffer);
-  AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferCarriesData) {
-  const DvrGlobalBufferKey buffer_name = 110;
-
-  uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                   AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  constexpr size_t size = 1024 * sizeof(uint64_t);
-  constexpr uint64_t value = 0x123456787654321;
-
-  {
-    // Allocate some data and set it to something.
-    DvrBuffer* setup_buffer = nullptr;
-    int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
-    ASSERT_NE(nullptr, setup_buffer);
-    ASSERT_EQ(0, e1);
-
-    AHardwareBuffer* hardware_buffer = nullptr;
-    int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-    ASSERT_EQ(0, e2);
-    ASSERT_NE(nullptr, hardware_buffer);
-
-    void* buffer;
-    int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-    ASSERT_EQ(0, e3);
-    ASSERT_NE(nullptr, buffer);
-    // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-    uint64_t* data = static_cast<uint64_t*>(buffer);
-    constexpr size_t num_values = size / sizeof(uint64_t);
-    for (size_t i = 0; i < num_values; ++i) {
-      data[i] = value;
-    }
-
-    int32_t fence = -1;
-    int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-    ASSERT_EQ(0, e4);
-
-    dvrBufferDestroy(setup_buffer);
-    AHardwareBuffer_release(hardware_buffer);
-  }
-
-  {
-    // Get the buffer and check that all the data is still present.
-    DvrBuffer* setup_buffer = nullptr;
-    int e1 = dvrGetGlobalBuffer(buffer_name, &setup_buffer);
-    ASSERT_NE(nullptr, setup_buffer);
-    ASSERT_EQ(0, e1);
-
-    AHardwareBuffer* hardware_buffer = nullptr;
-    int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-    ASSERT_EQ(0, e2);
-    ASSERT_NE(nullptr, hardware_buffer);
-
-    void* buffer;
-    int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-    ASSERT_EQ(0, e3);
-    ASSERT_NE(nullptr, buffer);
-    // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-    uint64_t* data = static_cast<uint64_t*>(buffer);
-    constexpr size_t num_values = size / sizeof(uint64_t);
-    bool is_equal = true;
-    for (size_t i = 0; i < num_values; ++i) {
-      is_equal &= (data[i] == value);
-    }
-    ASSERT_TRUE(is_equal);
-
-    int32_t fence = -1;
-    int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-    ASSERT_EQ(0, e4);
-
-    dvrBufferDestroy(setup_buffer);
-    AHardwareBuffer_release(hardware_buffer);
-  }
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferZeroed) {
-  const DvrGlobalBufferKey buffer_name = 120;
-
-  // Allocate 1MB and check that it is all zeros.
-  uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                   AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  constexpr size_t size = 1024 * 1024;
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e1);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer);
-
-  void* buffer;
-  int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-  ASSERT_EQ(0, e3);
-  ASSERT_NE(nullptr, buffer);
-  // Verify that the buffer pointer is at least 16 byte aligned.
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-  uint64_t* data = static_cast<uint64_t*>(buffer);
-  constexpr size_t num_values = size / sizeof(uint64_t);
-  uint64_t zero = 0;
-  for (size_t i = 0; i < num_values; ++i) {
-    zero |= data[i];
-  }
-  ASSERT_EQ(0U, zero);
-
-  int32_t fence = -1;
-  int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-  ASSERT_EQ(0, e4);
-
-  dvrBufferDestroy(setup_buffer);
-  AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestVrflingerConfigBuffer) {
-  const DvrGlobalBufferKey buffer_name =
-      DvrGlobalBuffers::kVrFlingerConfigBufferKey;
-
-  // First delete any existing buffer so we can test the failure case.
-  dvrDeleteGlobalBuffer(buffer_name);
-
-  const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                         AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
-
-  size_t correct_size = DvrConfigRing::MemorySize();
-  size_t wrong_size = DvrConfigRing::MemorySize(0);
-
-  // Setup an invalid config buffer (too small) and assert that it fails.
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_name, wrong_size, usage, &setup_buffer);
-  ASSERT_EQ(nullptr, setup_buffer);
-  ASSERT_GT(0, e1);
-
-  // Setup a correct config buffer.
-  int e2 =
-      dvrSetupGlobalBuffer(buffer_name, correct_size, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e2);
-
-  dvrBufferDestroy(setup_buffer);
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_tracking-test.cpp b/libs/vr/libdvr/tests/dvr_tracking-test.cpp
deleted file mode 100644
index 3b6d6e1..0000000
--- a/libs/vr/libdvr/tests/dvr_tracking-test.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <android/log.h>
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-namespace {
-
-class DvrTrackingTest : public DvrApiTest {};
-
-#if DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, Implemented) {
-  ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
-  ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateFailsForInvalidInput) {
-  int ret;
-  ret = api_.TrackingCameraCreate(nullptr);
-  EXPECT_EQ(ret, -EINVAL);
-
-  DvrTrackingCamera* camera = reinterpret_cast<DvrTrackingCamera*>(42);
-  ret = api_.TrackingCameraCreate(&camera);
-  EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateDestroy) {
-  DvrTrackingCamera* camera = nullptr;
-  int ret = api_.TrackingCameraCreate(&camera);
-
-  EXPECT_EQ(ret, 0);
-  ASSERT_TRUE(camera != nullptr);
-
-  api_.TrackingCameraDestroy(camera);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateFailsForInvalidInput) {
-  int ret;
-  ret = api_.TrackingFeatureExtractorCreate(nullptr);
-  EXPECT_EQ(ret, -EINVAL);
-
-  DvrTrackingFeatureExtractor* camera =
-      reinterpret_cast<DvrTrackingFeatureExtractor*>(42);
-  ret = api_.TrackingFeatureExtractorCreate(&camera);
-  EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateDestroy) {
-  DvrTrackingFeatureExtractor* camera = nullptr;
-  int ret = api_.TrackingFeatureExtractorCreate(&camera);
-
-  EXPECT_EQ(ret, 0);
-  ASSERT_TRUE(camera != nullptr);
-
-  api_.TrackingFeatureExtractorDestroy(camera);
-}
-
-#else  // !DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, NotImplemented) {
-  ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
-  EXPECT_EQ(api_.TrackingCameraCreate(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingCameraStart(nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingCameraStop(nullptr), -ENOSYS);
-
-  ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-
-  EXPECT_EQ(api_.TrackingFeatureExtractorCreate(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorStart(nullptr, nullptr, nullptr),
-            -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorStop(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorProcessBuffer(nullptr, nullptr,
-                                                       nullptr, nullptr),
-            -ENOSYS);
-
-  ASSERT_TRUE(api_.TrackingSensorsCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsStart != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsStop != nullptr);
-
-  EXPECT_EQ(api_.TrackingSensorsCreate(nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingSensorsStart(nullptr, nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingSensorsStop(nullptr), -ENOSYS);
-}
-
-#endif  // DVR_TRACKING_IMPLEMENTED
-
-}  // namespace
