diff options
author | 2020-04-13 18:57:54 -0700 | |
---|---|---|
committer | 2020-04-14 11:45:29 -0700 | |
commit | d0d6ccd726a2dd70c4df080e32d1e89d9e3f8640 (patch) | |
tree | b10cae93a96f3e5840701253c58582c23e64b381 | |
parent | 748bae0bc62f77f136528feeba7b4b5208b2509e (diff) |
Remove binder-based BufferHub from libui
We are removing Binder-based BufferHub from Android. Please refer to
b/147002762 for details. In short, those services and libraries were
originally created as a major refactor for a future product line. As
part of a strategy shift, these components are no longer needed.
Bug: 147002762
Test: Build and flash blueline
Merged-In: If5e64880911f2271a297b1628079261a4251f9e3
Change-Id: I9f7ac210b23b774d44c8fa85401f0aaf690c66e5
31 files changed, 0 insertions, 3439 deletions
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp index 4be014fbb1..489f3c356b 100644 --- a/libs/gui/BufferHubProducer.cpp +++ b/libs/gui/BufferHubProducer.cpp @@ -19,7 +19,6 @@ #include <inttypes.h> #include <log/log.h> #include <system/window.h> -#include <ui/BufferHubBuffer.h> namespace android { diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index ba6255dcab..458ee675d8 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -36,9 +36,6 @@ cc_library_shared { srcs: [ "ColorSpace.cpp", - "BufferHubBuffer.cpp", - "BufferHubEventFd.cpp", - "BufferHubMetadata.cpp", "DebugUtils.cpp", "Fence.cpp", "FenceTime.cpp", @@ -72,7 +69,6 @@ cc_library_shared { //defaults: ["libui-validate-regions-defaults"], shared_libs: [ - "android.frameworks.bufferhub@1.0", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.allocator@4.0", @@ -109,30 +105,20 @@ cc_library_shared { vendor: { cflags: ["-DLIBUI_IN_VNDK"], exclude_srcs: [ - "BufferHubBuffer.cpp", - "BufferHubEventFd.cpp", - "BufferHubMetadata.cpp", ], exclude_header_libs: [ - "libbufferhub_headers", - "libdvr_headers", ], exclude_shared_libs: [ - "android.frameworks.bufferhub@1.0", - "libpdx_default_transport", ], }, }, header_libs: [ "libbase_headers", - "libbufferhub_headers", - "libdvr_headers", "libnativebase_headers", "libnativewindow_headers", "libhardware_headers", "libui_headers", - "libpdx_headers", ], export_static_lib_headers: [ diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp deleted file mode 100644 index 1dfc1e9e88..0000000000 --- a/libs/ui/BufferHubBuffer.cpp +++ /dev/null @@ -1,358 +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 "BufferHubBuffer" -#include <poll.h> - -#include <android-base/unique_fd.h> -#include <android/frameworks/bufferhub/1.0/IBufferHub.h> -#include <log/log.h> -#include <ui/BufferHubBuffer.h> -#include <ui/BufferHubDefs.h> -#include <utils/Trace.h> - -using ::android::base::unique_fd; -using ::android::BufferHubDefs::isAnyClientAcquired; -using ::android::BufferHubDefs::isAnyClientGained; -using ::android::BufferHubDefs::isClientAcquired; -using ::android::BufferHubDefs::isClientGained; -using ::android::BufferHubDefs::isClientPosted; -using ::android::BufferHubDefs::isClientReleased; -using ::android::frameworks::bufferhub::V1_0::BufferHubStatus; -using ::android::frameworks::bufferhub::V1_0::BufferTraits; -using ::android::frameworks::bufferhub::V1_0::IBufferClient; -using ::android::frameworks::bufferhub::V1_0::IBufferHub; -using ::android::hardware::hidl_handle; -using ::android::hardware::graphics::common::V1_2::HardwareBufferDescription; - -namespace android { - -std::unique_ptr<BufferHubBuffer> BufferHubBuffer::create(uint32_t width, uint32_t height, - uint32_t layerCount, uint32_t format, - uint64_t usage, size_t userMetadataSize) { - auto buffer = std::unique_ptr<BufferHubBuffer>( - new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize)); - return buffer->isValid() ? std::move(buffer) : nullptr; -} - -std::unique_ptr<BufferHubBuffer> BufferHubBuffer::import(const sp<NativeHandle>& token) { - if (token == nullptr || token.get() == nullptr) { - ALOGE("%s: token cannot be nullptr!", __FUNCTION__); - return nullptr; - } - - auto buffer = std::unique_ptr<BufferHubBuffer>(new BufferHubBuffer(token)); - return buffer->isValid() ? std::move(buffer) : nullptr; -} - -BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, - uint32_t format, uint64_t usage, size_t userMetadataSize) { - ATRACE_CALL(); - ALOGD("%s: width=%u height=%u layerCount=%u, format=%u " - "usage=%" PRIx64 " mUserMetadataSize=%zu", - __FUNCTION__, width, height, layerCount, format, usage, userMetadataSize); - - sp<IBufferHub> bufferhub = IBufferHub::getService(); - if (bufferhub.get() == nullptr) { - ALOGE("%s: BufferHub service not found!", __FUNCTION__); - return; - } - - AHardwareBuffer_Desc aDesc = {width, height, layerCount, format, - usage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL}; - HardwareBufferDescription desc; - memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription)); - - BufferHubStatus ret; - sp<IBufferClient> client; - BufferTraits bufferTraits; - IBufferHub::allocateBuffer_cb allocCb = [&](const auto& status, const auto& outClient, - const auto& outTraits) { - ret = status; - client = std::move(outClient); - bufferTraits = std::move(outTraits); - }; - - if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), allocCb).isOk()) { - ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__); - return; - } else if (ret != BufferHubStatus::NO_ERROR) { - ALOGE("%s: allocateBuffer failed with error %u.", __FUNCTION__, ret); - return; - } else if (client == nullptr) { - ALOGE("%s: allocateBuffer got null BufferClient.", __FUNCTION__); - return; - } - - const int importRet = initWithBufferTraits(bufferTraits); - if (importRet < 0) { - ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet)); - client->close(); - } - mBufferClient = std::move(client); -} - -BufferHubBuffer::BufferHubBuffer(const sp<NativeHandle>& token) { - sp<IBufferHub> bufferhub = IBufferHub::getService(); - if (bufferhub.get() == nullptr) { - ALOGE("%s: BufferHub service not found!", __FUNCTION__); - return; - } - - BufferHubStatus ret; - sp<IBufferClient> client; - BufferTraits bufferTraits; - IBufferHub::importBuffer_cb importCb = [&](const auto& status, const auto& outClient, - const auto& outTraits) { - ret = status; - client = std::move(outClient); - bufferTraits = std::move(outTraits); - }; - - // hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership - // transfer. - if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), importCb).isOk()) { - ALOGE("%s: importBuffer transaction failed!", __FUNCTION__); - return; - } else if (ret != BufferHubStatus::NO_ERROR) { - ALOGE("%s: importBuffer failed with error %u.", __FUNCTION__, ret); - return; - } else if (client == nullptr) { - ALOGE("%s: importBuffer got null BufferClient.", __FUNCTION__); - return; - } - - const int importRet = initWithBufferTraits(bufferTraits); - if (importRet < 0) { - ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet)); - client->close(); - } - mBufferClient = std::move(client); -} - -BufferHubBuffer::~BufferHubBuffer() { - // Close buffer client to avoid possible race condition: user could first duplicate and hold - // token with the original buffer gone, and then try to import the token. The close function - // will explicitly invalidate the token to avoid this. - if (mBufferClient != nullptr) { - if (!mBufferClient->close().isOk()) { - ALOGE("%s: close BufferClient transaction failed!", __FUNCTION__); - } - } -} - -int BufferHubBuffer::initWithBufferTraits(const BufferTraits& bufferTraits) { - ATRACE_CALL(); - - if (bufferTraits.bufferInfo.getNativeHandle() == nullptr) { - ALOGE("%s: missing buffer info handle.", __FUNCTION__); - return -EINVAL; - } - - if (bufferTraits.bufferHandle.getNativeHandle() == nullptr) { - ALOGE("%s: missing gralloc handle.", __FUNCTION__); - return -EINVAL; - } - - // Import fds. Dup fds because hidl_handle owns the fds. - unique_fd ashmemFd(fcntl(bufferTraits.bufferInfo->data[0], F_DUPFD_CLOEXEC, 0)); - mMetadata = BufferHubMetadata::import(std::move(ashmemFd)); - if (!mMetadata.isValid()) { - ALOGE("%s: Received an invalid metadata.", __FUNCTION__); - return -EINVAL; - } - - mEventFd = BufferHubEventFd(fcntl(bufferTraits.bufferInfo->data[1], F_DUPFD_CLOEXEC, 0)); - if (!mEventFd.isValid()) { - ALOGE("%s: Received ad invalid event fd.", __FUNCTION__); - return -EINVAL; - } - - int bufferId = bufferTraits.bufferInfo->data[2]; - if (bufferId < 0) { - ALOGE("%s: Received an invalid (negative) id.", __FUNCTION__); - return -EINVAL; - } - - uint32_t clientBitMask; - memcpy(&clientBitMask, &bufferTraits.bufferInfo->data[3], sizeof(clientBitMask)); - if (clientBitMask == 0U) { - ALOGE("%s: Received an invalid client state mask.", __FUNCTION__); - return -EINVAL; - } - - uint32_t userMetadataSize; - memcpy(&userMetadataSize, &bufferTraits.bufferInfo->data[4], sizeof(userMetadataSize)); - if (mMetadata.userMetadataSize() != userMetadataSize) { - ALOGE("%s: user metadata size not match: expected %u, actual %zu.", __FUNCTION__, - userMetadataSize, mMetadata.userMetadataSize()); - return -EINVAL; - } - - size_t metadataSize = static_cast<size_t>(mMetadata.metadataSize()); - if (metadataSize < BufferHubDefs::kMetadataHeaderSize) { - ALOGE("%s: metadata too small: %zu", __FUNCTION__, metadataSize); - return -EINVAL; - } - - // Populate shortcuts to the atomics in metadata. - auto metadataHeader = mMetadata.metadataHeader(); - mBufferState = &metadataHeader->bufferState; - mFenceState = &metadataHeader->fenceState; - mActiveClientsBitMask = &metadataHeader->activeClientsBitMask; - // The C++ standard recommends (but does not require) that lock-free atomic operations are - // also address-free, that is, suitable for communication between processes using shared - // memory. - LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) || - !std::atomic_is_lock_free(mFenceState) || - !std::atomic_is_lock_free(mActiveClientsBitMask), - "Atomic variables in ashmen are not lock free."); - - // Import the buffer: We only need to hold on the native_handle_t here so that - // GraphicBuffer instance can be created in future. - mBufferHandle = std::move(bufferTraits.bufferHandle); - memcpy(&mBufferDesc, &bufferTraits.bufferDesc, sizeof(AHardwareBuffer_Desc)); - - mId = bufferId; - mClientStateMask = clientBitMask; - - // TODO(b/112012161) Set up shared fences. - ALOGD("%s: id=%d, mBufferState=%" PRIx32 ".", __FUNCTION__, mId, - mBufferState->load(std::memory_order_acquire)); - return 0; -} - -int BufferHubBuffer::gain() { - uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire); - if (isClientGained(currentBufferState, mClientStateMask)) { - ALOGV("%s: Buffer is already gained by this client %" PRIx32 ".", __FUNCTION__, - mClientStateMask); - return 0; - } - do { - if (isAnyClientGained(currentBufferState & (~mClientStateMask)) || - isAnyClientAcquired(currentBufferState)) { - ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx32 " state=%" PRIx32 ".", - __FUNCTION__, mId, mClientStateMask, currentBufferState); - return -EBUSY; - } - // Change the buffer state to gained state, whose value happens to be the same as - // mClientStateMask. - } while (!mBufferState->compare_exchange_weak(currentBufferState, mClientStateMask, - std::memory_order_acq_rel, - std::memory_order_acquire)); - // TODO(b/119837586): Update fence state and return GPU fence. - return 0; -} - -int BufferHubBuffer::post() { - uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire); - uint32_t updatedBufferState = (~mClientStateMask) & BufferHubDefs::kHighBitsMask; - do { - if (!isClientGained(currentBufferState, mClientStateMask)) { - ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d " - "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".", - __FUNCTION__, mId, mClientStateMask, currentBufferState); - return -EBUSY; - } - // Set the producer client buffer state to released, other clients' buffer state to posted. - // Post to all existing and non-existing clients. - } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState, - std::memory_order_acq_rel, - std::memory_order_acquire)); - // TODO(b/119837586): Update fence state and return GPU fence if needed. - return 0; -} - -int BufferHubBuffer::acquire() { - uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire); - if (isClientAcquired(currentBufferState, mClientStateMask)) { - ALOGV("%s: Buffer is already acquired by this client %" PRIx32 ".", __FUNCTION__, - mClientStateMask); - return 0; - } - uint32_t updatedBufferState = 0U; - do { - if (!isClientPosted(currentBufferState, mClientStateMask)) { - ALOGE("%s: Cannot acquire a buffer that is not in posted state. buffer_id=%d " - "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".", - __FUNCTION__, mId, mClientStateMask, currentBufferState); - return -EBUSY; - } - // Change the buffer state for this consumer from posted to acquired. - updatedBufferState = currentBufferState ^ mClientStateMask; - } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState, - std::memory_order_acq_rel, - std::memory_order_acquire)); - // TODO(b/119837586): Update fence state and return GPU fence. - return 0; -} - -int BufferHubBuffer::release() { - uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire); - if (isClientReleased(currentBufferState, mClientStateMask)) { - ALOGV("%s: Buffer is already released by this client %" PRIx32 ".", __FUNCTION__, - mClientStateMask); - return 0; - } - uint32_t updatedBufferState = 0U; - do { - updatedBufferState = currentBufferState & (~mClientStateMask); - } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState, - std::memory_order_acq_rel, - std::memory_order_acquire)); - // TODO(b/119837586): Update fence state and return GPU fence if needed. - return 0; -} - -bool BufferHubBuffer::isReleased() const { - return (mBufferState->load(std::memory_order_acquire) & - mActiveClientsBitMask->load(std::memory_order_acquire)) == 0; -} - -bool BufferHubBuffer::isValid() const { - return mBufferHandle.getNativeHandle() != nullptr && mId >= 0 && mClientStateMask != 0U && - mEventFd.get() >= 0 && mMetadata.isValid() && mBufferClient != nullptr; -} - -sp<NativeHandle> BufferHubBuffer::duplicate() { - if (mBufferClient == nullptr) { - ALOGE("%s: missing BufferClient!", __FUNCTION__); - return nullptr; - } - - hidl_handle token; - BufferHubStatus ret; - IBufferClient::duplicate_cb dupCb = [&](const auto& outToken, const auto& status) { - token = std::move(outToken); - ret = status; - }; - - if (!mBufferClient->duplicate(dupCb).isOk()) { - ALOGE("%s: duplicate transaction failed!", __FUNCTION__); - return nullptr; - } else if (ret != BufferHubStatus::NO_ERROR) { - ALOGE("%s: duplicate failed with error %u.", __FUNCTION__, ret); - return nullptr; - } else if (token.getNativeHandle() == nullptr) { - ALOGE("%s: duplicate got null token.", __FUNCTION__); - return nullptr; - } - - return NativeHandle::create(native_handle_clone(token.getNativeHandle()), /*ownsHandle=*/true); -} - -} // namespace android diff --git a/libs/ui/BufferHubEventFd.cpp b/libs/ui/BufferHubEventFd.cpp deleted file mode 100644 index bffc2ca803..0000000000 --- a/libs/ui/BufferHubEventFd.cpp +++ /dev/null @@ -1,49 +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. - */ - -#include <sys/eventfd.h> - -#include <log/log.h> -#include <ui/BufferHubEventFd.h> - -namespace android { - -BufferHubEventFd::BufferHubEventFd() : mFd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) {} - -BufferHubEventFd::BufferHubEventFd(int fd) : mFd(fd) {} - -status_t BufferHubEventFd::signal() const { - if (!isValid()) { - ALOGE("%s: cannot signal an invalid eventfd.", __FUNCTION__); - return DEAD_OBJECT; - } - - eventfd_write(mFd.get(), 1); - return OK; -} - -status_t BufferHubEventFd::clear() const { - if (!isValid()) { - ALOGE("%s: cannot clear an invalid eventfd.", __FUNCTION__); - return DEAD_OBJECT; - } - - eventfd_t value; - eventfd_read(mFd.get(), &value); - return OK; -} - -} // namespace android diff --git a/libs/ui/BufferHubMetadata.cpp b/libs/ui/BufferHubMetadata.cpp deleted file mode 100644 index 05bc7ddfbe..0000000000 --- a/libs/ui/BufferHubMetadata.cpp +++ /dev/null @@ -1,104 +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. - */ - -#include <errno.h> -#include <sys/mman.h> -#include <limits> - -#include <cutils/ashmem.h> -#include <log/log.h> -#include <ui/BufferHubMetadata.h> - -namespace android { - -namespace { - -static const int kAshmemProt = PROT_READ | PROT_WRITE; - -} // namespace - -using BufferHubDefs::kMetadataHeaderSize; -using BufferHubDefs::MetadataHeader; - -/* static */ -BufferHubMetadata BufferHubMetadata::create(size_t userMetadataSize) { - // The size the of metadata buffer is used as the "width" parameter during allocation. Thus it - // cannot overflow uint32_t. - if (userMetadataSize >= (std::numeric_limits<uint32_t>::max() - kMetadataHeaderSize)) { - ALOGE("BufferHubMetadata::Create: metadata size too big: %zu.", userMetadataSize); - return {}; - } - - const size_t metadataSize = userMetadataSize + kMetadataHeaderSize; - int fd = ashmem_create_region(/*name=*/"BufferHubMetadata", metadataSize); - if (fd < 0) { - ALOGE("BufferHubMetadata::Create: failed to create ashmem region."); - return {}; - } - - // Hand over the ownership of the fd to a unique_fd immediately after the successful - // return of ashmem_create_region. The ashmemFd is going to own the fd and to prevent fd - // leaks during error handling. - unique_fd ashmemFd{fd}; - - if (ashmem_set_prot_region(ashmemFd.get(), kAshmemProt) != 0) { - ALOGE("BufferHubMetadata::Create: failed to set protect region."); - return {}; - } - - return BufferHubMetadata::import(std::move(ashmemFd)); -} - -/* static */ -BufferHubMetadata BufferHubMetadata::import(unique_fd ashmemFd) { - if (!ashmem_valid(ashmemFd.get())) { - ALOGE("BufferHubMetadata::Import: invalid ashmem fd."); - return {}; - } - - size_t metadataSize = static_cast<size_t>(ashmem_get_size_region(ashmemFd.get())); - size_t userMetadataSize = metadataSize - kMetadataHeaderSize; - - // Note that here the buffer state is mapped from shared memory as an atomic object. The - // std::atomic's constructor will not be called so that the original value stored in the memory - // region can be preserved. - auto metadataHeader = static_cast<MetadataHeader*>(mmap(nullptr, metadataSize, kAshmemProt, - MAP_SHARED, ashmemFd.get(), - /*offset=*/0)); - if (metadataHeader == nullptr) { - ALOGE("BufferHubMetadata::Import: failed to map region."); - return {}; - } - - return BufferHubMetadata(userMetadataSize, std::move(ashmemFd), metadataHeader); -} - -BufferHubMetadata::BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd, - MetadataHeader* metadataHeader) - : mUserMetadataSize(userMetadataSize), - mAshmemFd(std::move(ashmemFd)), - mMetadataHeader(metadataHeader) {} - -BufferHubMetadata::~BufferHubMetadata() { - if (mMetadataHeader != nullptr) { - int ret = munmap(mMetadataHeader, metadataSize()); - ALOGE_IF(ret != 0, - "BufferHubMetadata::~BufferHubMetadata: failed to unmap ashmem, error=%d.", errno); - mMetadataHeader = nullptr; - } -} - -} // namespace android diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 05fc590bac..3732fee7f2 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -23,10 +23,6 @@ #include <grallocusage/GrallocUsageConversion.h> -#ifndef LIBUI_IN_VNDK -#include <ui/BufferHubBuffer.h> -#endif // LIBUI_IN_VNDK - #include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBufferMapper.h> #include <utils/Trace.h> @@ -110,22 +106,6 @@ GraphicBuffer::GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod m inUsage, inStride); } -#ifndef LIBUI_IN_VNDK -GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() { - if (buffer == nullptr) { - mInitCheck = BAD_VALUE; - return; - } - - mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, - buffer->desc().width, buffer->desc().height, - static_cast<PixelFormat>(buffer->desc().format), - buffer->desc().layers, buffer->desc().usage, buffer->desc().stride); - mBufferId = buffer->id(); - mBufferHubBuffer = std::move(buffer); -} -#endif // LIBUI_IN_VNDK - GraphicBuffer::~GraphicBuffer() { ATRACE_CALL(); @@ -374,29 +354,14 @@ status_t GraphicBuffer::isSupported(uint32_t inWidth, uint32_t inHeight, PixelFo } size_t GraphicBuffer::getFlattenedSize() const { -#ifndef LIBUI_IN_VNDK - if (mBufferHubBuffer != nullptr) { - return 48; - } -#endif return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int); } size_t GraphicBuffer::getFdCount() const { -#ifndef LIBUI_IN_VNDK - if (mBufferHubBuffer != nullptr) { - return 0; - } -#endif return static_cast<size_t>(handle ? mTransportNumFds : 0); } status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { -#ifndef LIBUI_IN_VNDK - if (mBufferHubBuffer != nullptr) { - return flattenBufferHubBuffer(buffer, size); - } -#endif size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); if (size < sizeNeeded) return NO_MEMORY; @@ -453,12 +418,6 @@ status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& } else if (buf[0] == 'GBFR') { // old version, when usage bits were 32-bits flattenWordCount = 12; - } else if (buf[0] == 'BHBB') { // BufferHub backed buffer. -#ifndef LIBUI_IN_VNDK - return unflattenBufferHubBuffer(buffer, size); -#else - return BAD_TYPE; -#endif } else { return BAD_TYPE; } @@ -565,76 +524,6 @@ void GraphicBuffer::addDeathCallback(GraphicBufferDeathCallback deathCallback, v mDeathCallbacks.emplace_back(deathCallback, context); } -#ifndef LIBUI_IN_VNDK -status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size) const { - sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate(); - if (tokenHandle == nullptr || tokenHandle->handle() == nullptr || - tokenHandle->handle()->numFds != 0) { - return BAD_VALUE; - } - - // Size needed for one label, one number of ints inside the token, one generation number and - // the token itself. - int numIntsInToken = tokenHandle->handle()->numInts; - const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); - if (size < sizeNeeded) { - ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, - static_cast<int>(sizeNeeded), static_cast<int>(size)); - return NO_MEMORY; - } - size -= sizeNeeded; - - int* buf = static_cast<int*>(buffer); - buf[0] = 'BHBB'; - buf[1] = numIntsInToken; - memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int)); - buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber); - - return NO_ERROR; -} - -status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size) { - const int* buf = static_cast<const int*>(buffer); - int numIntsInToken = buf[1]; - // Size needed for one label, one number of ints inside the token, one generation number and - // the token itself. - const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); - if (size < sizeNeeded) { - ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, - static_cast<int>(sizeNeeded), static_cast<int>(size)); - return NO_MEMORY; - } - size -= sizeNeeded; - native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken); - memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int)); - sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true); - std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle); - if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) { - return BAD_VALUE; - } - // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object. - if (handle) { - free_handle(); - } - mId = 0; - mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]); - mInitCheck = - initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, - bufferHubBuffer->desc().width, bufferHubBuffer->desc().height, - static_cast<PixelFormat>(bufferHubBuffer->desc().format), - bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage, - bufferHubBuffer->desc().stride); - mBufferId = bufferHubBuffer->id(); - mBufferHubBuffer = std::move(bufferHubBuffer); - - return NO_ERROR; -} - -bool GraphicBuffer::isBufferHubBuffer() const { - return mBufferHubBuffer != nullptr; -} -#endif // LIBUI_IN_VNDK - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h deleted file mode 100644 index 5ba189c2c3..0000000000 --- a/libs/ui/include/ui/BufferHubBuffer.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_BUFFER_HUB_BUFFER_H_ -#define ANDROID_BUFFER_HUB_BUFFER_H_ - -#include <android/frameworks/bufferhub/1.0/IBufferClient.h> -#include <android/hardware_buffer.h> -#include <cutils/native_handle.h> -#include <ui/BufferHubDefs.h> -#include <ui/BufferHubEventFd.h> -#include <ui/BufferHubMetadata.h> -#include <utils/NativeHandle.h> - -namespace android { - -class BufferHubBuffer { -public: - // Allocates a standalone BufferHubBuffer. - static std::unique_ptr<BufferHubBuffer> create(uint32_t width, uint32_t height, - uint32_t layerCount, uint32_t format, - uint64_t usage, size_t userMetadataSize); - - // Imports the given token to a BufferHubBuffer. Not taking ownership of the token. - static std::unique_ptr<BufferHubBuffer> import(const sp<NativeHandle>& token); - - BufferHubBuffer(const BufferHubBuffer&) = delete; - void operator=(const BufferHubBuffer&) = delete; - - virtual ~BufferHubBuffer(); - - // Gets ID of the buffer client. All BufferHubBuffer clients derived from the same buffer in - // BufferHub share the same buffer id. - int id() const { return mId; } - - // Returns the buffer description, which is guaranteed to be faithful values from BufferHub. - const AHardwareBuffer_Desc& desc() const { return mBufferDesc; } - - // Duplicate the underlying Gralloc buffer handle. Caller is responsible to free the handle - // after use. - native_handle_t* duplicateHandle() { - return native_handle_clone(mBufferHandle.getNativeHandle()); - } - - const BufferHubEventFd& eventFd() const { return mEventFd; } - - // Returns the current value of MetadataHeader::bufferState. - uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); } - - // A state mask which is unique to a buffer hub client among all its siblings sharing the same - // concrete graphic buffer. - uint32_t clientStateMask() const { return mClientStateMask; } - - size_t userMetadataSize() const { return mMetadata.userMetadataSize(); } - - // Returns true if the BufferClient is still alive. - bool isConnected() const { return mBufferClient->ping().isOk(); } - - // Returns true if the buffer is valid: non-null buffer handle, valid id, valid client bit mask, - // valid metadata and valid buffer client - bool isValid() const; - - // Gains the buffer for exclusive write permission. Read permission is implied once a buffer is - // gained. - // The buffer can be gained as long as there is no other client in acquired or gained state. - int gain(); - - // Posts the gained buffer for other buffer clients to use the buffer. - // The buffer can be posted iff the buffer state for this client is gained. - // After posting the buffer, this client is put to released state and does not have access to - // the buffer for this cycle of the usage of the buffer. - int post(); - - // Acquires the buffer for shared read permission. - // The buffer can be acquired iff the buffer state for this client is posted. - int acquire(); - - // Releases the buffer. - // The buffer can be released from any buffer state. - // After releasing the buffer, this client no longer have any permissions to the buffer for the - // current cycle of the usage of the buffer. - int release(); - - // Returns whether the buffer is released by all active clients or not. - bool isReleased() const; - - // Creates a token that stands for this BufferHubBuffer client and could be used for Import to - // create another BufferHubBuffer. The new BufferHubBuffer will share the same underlying - // gralloc buffer and ashmem region for metadata. Not taking ownership of the token. - // Returns a valid token on success, nullptr on failure. - sp<NativeHandle> duplicate(); - -private: - BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format, - uint64_t usage, size_t userMetadataSize); - - BufferHubBuffer(const sp<NativeHandle>& token); - - int initWithBufferTraits(const frameworks::bufferhub::V1_0::BufferTraits& bufferTraits); - - // Global id for the buffer that is consistent across processes. - int mId = 0; - - // Client state mask of this BufferHubBuffer object. It is unique amoung all - // clients/users of the buffer. - uint32_t mClientStateMask = 0U; - - // Stores ground truth of the buffer. - AHardwareBuffer_Desc mBufferDesc; - - // Wraps the gralloc buffer handle of this buffer. - hardware::hidl_handle mBufferHandle; - - // Event fd used for signalling buffer state changes. Shared by all clients of the same buffer. - BufferHubEventFd mEventFd; - - // An ashmem-based metadata object. The same shared memory are mapped to the - // bufferhubd daemon and all buffer clients. - BufferHubMetadata mMetadata; - // Shortcuts to the atomics inside the header of mMetadata. - std::atomic<uint32_t>* mBufferState = nullptr; - std::atomic<uint32_t>* mFenceState = nullptr; - std::atomic<uint32_t>* mActiveClientsBitMask = nullptr; - - // HwBinder backend - sp<frameworks::bufferhub::V1_0::IBufferClient> mBufferClient; -}; - -} // namespace android - -#endif // ANDROID_BUFFER_HUB_BUFFER_H_ diff --git a/libs/ui/include/ui/BufferHubEventFd.h b/libs/ui/include/ui/BufferHubEventFd.h deleted file mode 100644 index 8772304c0f..0000000000 --- a/libs/ui/include/ui/BufferHubEventFd.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_BUFFER_HUB_EVENT_FD_H_ -#define ANDROID_BUFFER_HUB_EVENT_FD_H_ - -#include <android-base/unique_fd.h> -#include <utils/Errors.h> - -namespace android { - -class BufferHubEventFd { -public: - /** - * Constructs a valid event fd. - */ - BufferHubEventFd(); - - /** - * Constructs from a valid event fd. Caller is responsible for the validity of the fd. Takes - * ownership. - */ - BufferHubEventFd(int fd); - - /** - * Returns whether this BufferHubEventFd holds a valid event_fd. - */ - bool isValid() const { return get() >= 0; } - - /** - * Returns the fd number of the BufferHubEventFd object. Note that there is no ownership - * transfer. - */ - int get() const { return mFd.get(); } - - /** - * Signals the eventfd. - */ - status_t signal() const; - - /** - * Clears the signal from this eventfd if it is signaled. - */ - status_t clear() const; - -private: - base::unique_fd mFd; -}; - -} // namespace android - -#endif // ANDROID_BUFFER_HUB_EVENT_FD_H_ diff --git a/libs/ui/include/ui/BufferHubMetadata.h b/libs/ui/include/ui/BufferHubMetadata.h deleted file mode 100644 index 3482507399..0000000000 --- a/libs/ui/include/ui/BufferHubMetadata.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_BUFFER_HUB_METADATA_H_ -#define ANDROID_BUFFER_HUB_METADATA_H_ - -#include <android-base/unique_fd.h> -#include <ui/BufferHubDefs.h> - -namespace android { - -namespace { -using base::unique_fd; -} // namespace - -class BufferHubMetadata { -public: - // Creates a new BufferHubMetadata backed by an ashmem region. - // - // @param userMetadataSize Size in bytes of the user defined metadata. The entire metadata - // shared memory region to be allocated is the size of canonical - // BufferHubDefs::MetadataHeader plus userMetadataSize. - static BufferHubMetadata create(size_t userMetadataSize); - - // Imports an existing BufferHubMetadata from an ashmem FD. - // - // @param ashmemFd Ashmem file descriptor representing an ashmem region. - static BufferHubMetadata import(unique_fd ashmemFd); - - BufferHubMetadata() = default; - - BufferHubMetadata(BufferHubMetadata&& other) { *this = std::move(other); } - - ~BufferHubMetadata(); - - BufferHubMetadata& operator=(BufferHubMetadata&& other) { - if (this != &other) { - mUserMetadataSize = other.mUserMetadataSize; - other.mUserMetadataSize = 0; - - mAshmemFd = std::move(other.mAshmemFd); - - // The old raw mMetadataHeader pointer must be cleared, otherwise the destructor will - // automatically mummap() the shared memory. - mMetadataHeader = other.mMetadataHeader; - other.mMetadataHeader = nullptr; - } - return *this; - } - - // Returns true if the metadata is valid, i.e. the metadata has a valid ashmem fd and the ashmem - // has been mapped into virtual address space. - bool isValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; } - - size_t userMetadataSize() const { return mUserMetadataSize; } - size_t metadataSize() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; } - - const unique_fd& ashmemFd() const { return mAshmemFd; } - BufferHubDefs::MetadataHeader* metadataHeader() { return mMetadataHeader; } - -private: - BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd, - BufferHubDefs::MetadataHeader* metadataHeader); - - BufferHubMetadata(const BufferHubMetadata&) = delete; - void operator=(const BufferHubMetadata&) = delete; - - size_t mUserMetadataSize = 0; - unique_fd mAshmemFd; - BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr; -}; - -} // namespace android - -#endif // ANDROID_BUFFER_HUB_METADATA_H_ diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h index c195342705..013505a2c9 100644 --- a/libs/ui/include/ui/GraphicBuffer.h +++ b/libs/ui/include/ui/GraphicBuffer.h @@ -38,10 +38,6 @@ namespace android { -#ifndef LIBUI_IN_VNDK -class BufferHubBuffer; -#endif // LIBUI_IN_VNDK - class GraphicBufferMapper; using GraphicBufferDeathCallback = std::function<void(void* /*context*/, uint64_t bufferId)>; @@ -147,11 +143,6 @@ public: GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inUsage, std::string requestorName = "<Unknown>"); -#ifndef LIBUI_IN_VNDK - // Create a GraphicBuffer from an existing BufferHubBuffer. - GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer); -#endif // LIBUI_IN_VNDK - // return status status_t initCheck() const; @@ -163,7 +154,6 @@ public: uint32_t getLayerCount() const { return static_cast<uint32_t>(layerCount); } Rect getBounds() const { return Rect(width, height); } uint64_t getId() const { return mId; } - int32_t getBufferId() const { return mBufferId; } uint32_t getGenerationNumber() const { return mGenerationNumber; } void setGenerationNumber(uint32_t generation) { @@ -225,11 +215,6 @@ public: void addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context); -#ifndef LIBUI_IN_VNDK - // Returns whether this GraphicBuffer is backed by BufferHubBuffer. - bool isBufferHubBuffer() const; -#endif // LIBUI_IN_VNDK - private: ~GraphicBuffer(); @@ -275,12 +260,6 @@ private: uint64_t mId; - // System unique buffer ID. Note that this is different from mId, which is process unique. For - // GraphicBuffer backed by BufferHub, the mBufferId is a system unique identifier that stays the - // same cross process for the same chunck of underlying memory. Also note that this only applies - // to GraphicBuffers that are backed by BufferHub. - int32_t mBufferId = -1; - // Stores the generation number of this buffer. If this number does not // match the BufferQueue's internal generation number (set through // IGBP::setGenerationNumber), attempts to attach the buffer will fail. @@ -299,22 +278,6 @@ private: // and informs SurfaceFlinger that it should drop its strong pointer reference to the buffer. std::vector<std::pair<GraphicBufferDeathCallback, void* /*mDeathCallbackContext*/>> mDeathCallbacks; - -#ifndef LIBUI_IN_VNDK - // Flatten this GraphicBuffer object if backed by BufferHubBuffer. - status_t flattenBufferHubBuffer(void*& buffer, size_t& size) const; - - // Unflatten into BufferHubBuffer backed GraphicBuffer. - // Unflatten will fail if the original GraphicBuffer object is destructed. For instance, a - // GraphicBuffer backed by BufferHubBuffer_1 flatten in process/thread A, transport the token - // to process/thread B through a socket, BufferHubBuffer_1 dies and bufferhub invalidated the - // token. Race condition occurs between the invalidation of the token in bufferhub process and - // process/thread B trying to unflatten and import the buffer with that token. - status_t unflattenBufferHubBuffer(void const*& buffer, size_t& size); - - // Stores a BufferHubBuffer that handles buffer signaling, identification. - std::unique_ptr<BufferHubBuffer> mBufferHubBuffer; -#endif // LIBUI_IN_VNDK }; }; // namespace android diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp index 605c5a9ba0..b53342cb79 100644 --- a/libs/ui/tests/Android.bp +++ b/libs/ui/tests/Android.bp @@ -31,7 +31,6 @@ cc_test { cc_test { name: "GraphicBufferAllocator_test", header_libs: [ - "libdvr_headers", "libnativewindow_headers", ], static_libs: [ @@ -52,11 +51,9 @@ cc_test { cc_test { name: "GraphicBuffer_test", header_libs: [ - "libdvr_headers", "libnativewindow_headers", ], shared_libs: [ - "android.frameworks.bufferhub@1.0", "libcutils", "libhidlbase", "libui", @@ -71,11 +68,7 @@ cc_test { name: "GraphicBufferOverBinder_test", srcs: ["GraphicBufferOverBinder_test.cpp"], cflags: ["-Wall", "-Werror"], - header_libs: [ - "libdvr_headers", - ], shared_libs: [ - "android.frameworks.bufferhub@1.0", "libbinder", "libgui", "liblog", @@ -85,31 +78,6 @@ cc_test { } cc_test { - name: "BufferHub_test", - header_libs: [ - "libdvr_headers", - "libnativewindow_headers", - ], - static_libs: [ - "libgmock", - ], - shared_libs: [ - "android.frameworks.bufferhub@1.0", - "libcutils", - "libhidlbase", - "liblog", - "libui", - "libutils" - ], - srcs: [ - "BufferHubBuffer_test.cpp", - "BufferHubEventFd_test.cpp", - "BufferHubMetadata_test.cpp", - ], - cflags: ["-Wall", "-Werror"], -} - -cc_test { name: "Size_test", test_suites: ["device-tests"], shared_libs: ["libui"], diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp deleted file mode 100644 index 0c73a72deb..0000000000 --- a/libs/ui/tests/BufferHubBuffer_test.cpp +++ /dev/null @@ -1,477 +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. - */ - -#define LOG_TAG "BufferHubBufferTest" - -#include <errno.h> -#include <sys/epoll.h> - -#include <android/frameworks/bufferhub/1.0/IBufferHub.h> -#include <android/hardware_buffer.h> -#include <cutils/native_handle.h> -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <hidl/ServiceManagement.h> -#include <hwbinder/IPCThreadState.h> -#include <ui/BufferHubBuffer.h> -#include <ui/BufferHubEventFd.h> - -namespace android { - -namespace { - -using ::android::BufferHubDefs::isAnyClientAcquired; -using ::android::BufferHubDefs::isAnyClientGained; -using ::android::BufferHubDefs::isAnyClientPosted; -using ::android::BufferHubDefs::isClientAcquired; -using ::android::BufferHubDefs::isClientGained; -using ::android::BufferHubDefs::isClientPosted; -using ::android::BufferHubDefs::isClientReleased; -using ::android::BufferHubDefs::kMetadataHeaderSize; -using ::android::frameworks::bufferhub::V1_0::IBufferHub; -using ::testing::IsNull; -using ::testing::NotNull; - -const int kWidth = 640; -const int kHeight = 480; -const int kLayerCount = 1; -const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888; -const int kUsage = 0; -const AHardwareBuffer_Desc kDesc = {kWidth, kHeight, kLayerCount, kFormat, - kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL}; -const size_t kUserMetadataSize = 1; - -class BufferHubBufferTest : public ::testing::Test { -protected: - void SetUp() override { - android::hardware::ProcessState::self()->startThreadPool(); - - if (!BufferHubServiceRunning()) { - // TODO(b/112940221): Enforce the test cross all devices once BufferHub lands in Android - // R for all Android varieties. - GTEST_SKIP() << "Skip test as the BufferHub service is not running."; - } - } - - bool BufferHubServiceRunning() { - sp<IBufferHub> bufferhub = IBufferHub::getService(); - return bufferhub.get() != nullptr; - } -}; - -bool cmpAHardwareBufferDesc(const AHardwareBuffer_Desc& desc, const AHardwareBuffer_Desc& other) { - // Not comparing stride because it's unknown before allocation - return desc.format == other.format && desc.height == other.height && - desc.layers == other.layers && desc.usage == other.usage && desc.width == other.width; -} - -class BufferHubBufferStateTransitionTest : public BufferHubBufferTest { -protected: - void SetUp() override { - BufferHubBufferTest::SetUp(); - - if (IsSkipped()) { - // If the base class' SetUp() stated the test should be skipped, we should short - // circuit this sub-class' logic. - return; - } - - CreateTwoClientsOfABuffer(); - } - - std::unique_ptr<BufferHubBuffer> b1; - uint32_t b1ClientMask = 0U; - std::unique_ptr<BufferHubBuffer> b2; - uint32_t b2ClientMask = 0U; - -private: - // Creates b1 and b2 as the clients of the same buffer for testing. - void CreateTwoClientsOfABuffer(); -}; - -void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() { - b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize); - ASSERT_THAT(b1, NotNull()); - b1ClientMask = b1->clientStateMask(); - ASSERT_NE(b1ClientMask, 0U); - - sp<NativeHandle> token = b1->duplicate(); - ASSERT_THAT(token, NotNull()); - - b2 = BufferHubBuffer::import(token); - ASSERT_THAT(b2, NotNull()); - - b2ClientMask = b2->clientStateMask(); - ASSERT_NE(b2ClientMask, 0U); - ASSERT_NE(b2ClientMask, b1ClientMask); -} - -TEST_F(BufferHubBufferTest, CreateBufferFails) { - // Buffer Creation will fail: BLOB format requires height to be 1. - auto b1 = BufferHubBuffer::create(kWidth, /*height=*/2, kLayerCount, - /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize); - - EXPECT_THAT(b1, IsNull()); - - // Buffer Creation will fail: user metadata size too large. - auto b2 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - /*userMetadataSize=*/std::numeric_limits<size_t>::max()); - - EXPECT_THAT(b2, IsNull()); - - // Buffer Creation will fail: user metadata size too large. - const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize; - auto b3 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - userMetadataSize); - - EXPECT_THAT(b3, IsNull()); -} - -TEST_F(BufferHubBufferTest, CreateBuffer) { - auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - kUserMetadataSize); - ASSERT_THAT(b1, NotNull()); - EXPECT_TRUE(b1->isConnected()); - EXPECT_TRUE(b1->isValid()); - EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), kDesc)); - EXPECT_EQ(b1->userMetadataSize(), kUserMetadataSize); -} - -TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) { - auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - kUserMetadataSize); - ASSERT_THAT(b1, NotNull()); - EXPECT_TRUE(b1->isValid()); - - sp<NativeHandle> token = b1->duplicate(); - ASSERT_THAT(token, NotNull()); - - // The detached buffer should still be valid. - EXPECT_TRUE(b1->isConnected()); - EXPECT_TRUE(b1->isValid()); - - std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token); - - ASSERT_THAT(b2, NotNull()); - EXPECT_TRUE(b2->isValid()); - - EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), b2->desc())); - EXPECT_EQ(b1->userMetadataSize(), b2->userMetadataSize()); - - // These two buffer instances are based on the same physical buffer under the - // hood, so they should share the same id. - EXPECT_EQ(b1->id(), b2->id()); - // We use clientStateMask() to tell those two instances apart. - EXPECT_NE(b1->clientStateMask(), b2->clientStateMask()); - - // Both buffer instances should be in released state currently. - EXPECT_TRUE(b1->isReleased()); - EXPECT_TRUE(b2->isReleased()); - - // The event fd should behave like duped event fds. - const BufferHubEventFd& eventFd1 = b1->eventFd(); - ASSERT_GE(eventFd1.get(), 0); - const BufferHubEventFd& eventFd2 = b2->eventFd(); - ASSERT_GE(eventFd2.get(), 0); - - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - - // Add eventFd1 to epoll set, and signal eventFd2. - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e), 0) << strerror(errno); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - eventFd2.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - eventFd2.signal(); - eventFd2.clear(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubBufferTest, ImportFreedBuffer) { - auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - kUserMetadataSize); - ASSERT_THAT(b1, NotNull()); - EXPECT_TRUE(b1->isValid()); - - sp<NativeHandle> token = b1->duplicate(); - ASSERT_THAT(token, NotNull()); - - // Explicitly destroy b1. Backend buffer should be freed and token becomes invalid - b1.reset(); - - std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token); - - // Import should fail with INVALID_TOKEN - EXPECT_THAT(b2, IsNull()); -} - -// nullptr must not crash the service -TEST_F(BufferHubBufferTest, ImportNullToken) { - auto b1 = BufferHubBuffer::import(nullptr); - EXPECT_THAT(b1, IsNull()); -} - -TEST_F(BufferHubBufferTest, ImportInvalidToken) { - native_handle_t* token = native_handle_create(/*numFds=*/0, /*numInts=*/1); - token->data[0] = 0; - - sp<NativeHandle> tokenHandle = NativeHandle::create(token, /*ownHandle=*/true); - auto b1 = BufferHubBuffer::import(tokenHandle); - - EXPECT_THAT(b1, IsNull()); -} - -TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) { - ASSERT_TRUE(b1->isReleased()); - - // Successful gaining the buffer should change the buffer state bit of b1 to - // gained state, other client state bits to released state. - EXPECT_EQ(b1->gain(), 0); - EXPECT_TRUE(isClientGained(b1->bufferState(), b1ClientMask)); -} - -TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromGainedState) { - ASSERT_EQ(b1->gain(), 0); - auto currentBufferState = b1->bufferState(); - ASSERT_TRUE(isClientGained(currentBufferState, b1ClientMask)); - - // Gaining from gained state by the same client should not return error. - EXPECT_EQ(b1->gain(), 0); - - // Gaining from gained state by another client should return error. - EXPECT_EQ(b2->gain(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromAcquiredState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_EQ(b2->acquire(), 0); - ASSERT_TRUE(isAnyClientAcquired(b1->bufferState())); - - // Gaining from acquired state should fail. - EXPECT_EQ(b1->gain(), -EBUSY); - EXPECT_EQ(b2->gain(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromOtherClientInPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isAnyClientPosted(b1->bufferState())); - - // Gaining a buffer who has other posted client should succeed. - EXPECT_EQ(b1->gain(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromSelfInPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isAnyClientPosted(b1->bufferState())); - - // A posted client should be able to gain the buffer when there is no other clients in - // acquired state. - EXPECT_EQ(b2->gain(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromOtherInGainedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask)); - - EXPECT_EQ(b2->post(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromSelfInGainedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask)); - - EXPECT_EQ(b1->post(), 0); - auto currentBufferState = b1->bufferState(); - EXPECT_TRUE(isClientReleased(currentBufferState, b1ClientMask)); - EXPECT_TRUE(isClientPosted(currentBufferState, b2ClientMask)); -} - -TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isAnyClientPosted(b1->bufferState())); - - // Post from posted state should fail. - EXPECT_EQ(b1->post(), -EBUSY); - EXPECT_EQ(b2->post(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromAcquiredState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_EQ(b2->acquire(), 0); - ASSERT_TRUE(isAnyClientAcquired(b1->bufferState())); - - // Posting from acquired state should fail. - EXPECT_EQ(b1->post(), -EBUSY); - EXPECT_EQ(b2->post(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromReleasedState) { - ASSERT_TRUE(b1->isReleased()); - - // Posting from released state should fail. - EXPECT_EQ(b1->post(), -EBUSY); - EXPECT_EQ(b2->post(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask)); - - // Acquire from posted state should pass. - EXPECT_EQ(b2->acquire(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromOtherInPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask)); - - // Acquire from released state should fail, although there are other clients - // in posted state. - EXPECT_EQ(b1->acquire(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInAcquiredState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_EQ(b2->acquire(), 0); - auto currentBufferState = b1->bufferState(); - ASSERT_TRUE(isClientAcquired(currentBufferState, b2ClientMask)); - - // Acquiring from acquired state by the same client should not error out. - EXPECT_EQ(b2->acquire(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromReleasedState) { - ASSERT_TRUE(b1->isReleased()); - - // Acquiring form released state should fail. - EXPECT_EQ(b1->acquire(), -EBUSY); - EXPECT_EQ(b2->acquire(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromGainedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_TRUE(isAnyClientGained(b1->bufferState())); - - // Acquiring from gained state should fail. - EXPECT_EQ(b1->acquire(), -EBUSY); - EXPECT_EQ(b2->acquire(), -EBUSY); -} - -TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInReleasedState) { - ASSERT_TRUE(b1->isReleased()); - - EXPECT_EQ(b1->release(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInGainedState) { - ASSERT_TRUE(b1->isReleased()); - ASSERT_EQ(b1->gain(), 0); - ASSERT_TRUE(isAnyClientGained(b1->bufferState())); - - EXPECT_EQ(b1->release(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInPostedState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_TRUE(isAnyClientPosted(b1->bufferState())); - - EXPECT_EQ(b2->release(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInAcquiredState) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_EQ(b2->acquire(), 0); - ASSERT_TRUE(isAnyClientAcquired(b1->bufferState())); - - EXPECT_EQ(b2->release(), 0); -} - -TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) { - // 1 producer buffer and 1 consumer buffer initialised in testcase setup. - // Test if this set of basic operation succeed: - // Producer post three times to the consumer, and released by consumer. - for (int i = 0; i < 3; ++i) { - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - ASSERT_EQ(b2->acquire(), 0); - ASSERT_EQ(b2->release(), 0); - } -} - -TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) { - // Create a poducer buffer and gain. - std::unique_ptr<BufferHubBuffer> b1 = - BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - kUserMetadataSize); - ASSERT_THAT(b1, NotNull()); - ASSERT_EQ(b1->gain(), 0); - - // Create a consumer of the buffer and test if the consumer can acquire the - // buffer if producer posts. - sp<NativeHandle> token = b1->duplicate(); - ASSERT_THAT(token, NotNull()); - - std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token); - - ASSERT_THAT(b2, NotNull()); - ASSERT_NE(b1->clientStateMask(), b2->clientStateMask()); - - ASSERT_EQ(b1->post(), 0); - EXPECT_EQ(b2->acquire(), 0); -} - -TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) { - // Create a poducer buffer and post. - std::unique_ptr<BufferHubBuffer> b1 = - BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, - kUserMetadataSize); - ASSERT_EQ(b1->gain(), 0); - ASSERT_EQ(b1->post(), 0); - - // Create a consumer of the buffer and test if the consumer can acquire the - // buffer if producer posts. - sp<NativeHandle> token = b1->duplicate(); - ASSERT_THAT(token, NotNull()); - - std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token); - - ASSERT_THAT(b2, NotNull()); - ASSERT_NE(b1->clientStateMask(), b2->clientStateMask()); - - EXPECT_EQ(b2->acquire(), 0); -} - -} // namespace - -} // namespace android diff --git a/libs/ui/tests/BufferHubEventFd_test.cpp b/libs/ui/tests/BufferHubEventFd_test.cpp deleted file mode 100644 index ef1781f9d2..0000000000 --- a/libs/ui/tests/BufferHubEventFd_test.cpp +++ /dev/null @@ -1,428 +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. - */ - -#define LOG_TAG "BufferHubEventFdTest" - -#include <sys/epoll.h> -#include <sys/eventfd.h> - -#include <array> -#include <condition_variable> -#include <mutex> -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <log/log.h> -#include <ui/BufferHubEventFd.h> - -namespace android { - -namespace { - -const int kTimeout = 100; -const std::chrono::milliseconds kTimeoutMs(kTimeout); -const int kTestRuns = 5; - -using ::testing::Contains; -using BufferHubEventFdTest = ::testing::Test; - -} // namespace - -TEST_F(BufferHubEventFdTest, EventFd_testSingleEpollFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - eventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - // Check that it can receive consecutive signal. - eventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - // Check that it can receive consecutive signal from a duplicated eventfd. - BufferHubEventFd dupEventFd(dup(eventFd.get())); - ASSERT_TRUE(dupEventFd.isValid()); - dupEventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - dupEventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testCreateEpollFdAndAddSignaledEventFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - eventFd.signal(); - - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - - // Make sure that the epoll set has not been signal yet. - std::array<epoll_event, 1> events; - ASSERT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - // Check that adding an signaled fd into this epoll set will trigger the epoll set. - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testAddSignaledEventFdToEpollFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - - eventFd.signal(); - - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromAEventFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - std::array<epoll_event, 1> events; - for (int i = 0; i < kTestRuns; ++i) { - eventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - } -} - -TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromADuplicatedEventFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - base::unique_fd epollFd(epoll_create(64)); - ASSERT_GE(epollFd.get(), 0); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - BufferHubEventFd dupEventFd(dup(eventFd.get())); - ASSERT_TRUE(dupEventFd.isValid()); - - std::array<epoll_event, 1> events; - for (int i = 0; i < kTestRuns; ++i) { - dupEventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - } -} - -TEST_F(BufferHubEventFdTest, EventFd_testClear) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - - ASSERT_GE(epollFd.get(), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - eventFd.signal(); - eventFd.clear(); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testDupEventFd) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - - ASSERT_GE(epollFd.get(), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - // Technically, the dupliated eventFd and the original eventFd are pointing - // to the same kernel object. This test signals the duplicated eventFd but epolls the origianl - // eventFd. - BufferHubEventFd dupedEventFd(dup(eventFd.get())); - ASSERT_GE(dupedEventFd.get(), 0); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - dupedEventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - dupedEventFd.signal(); - - dupedEventFd.clear(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testTwoEpollFds) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd1(epoll_create(64)); - base::unique_fd epollFd2(epoll_create(64)); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - - ASSERT_GE(epollFd1.get(), 0); - ASSERT_GE(epollFd2.get(), 0); - - // Register the same eventFd to two EpollFds. - ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - std::array<epoll_event, 1> events; - EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0); - EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0); - - eventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 1); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0); - EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0); - - eventFd.signal(); - EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1); - - eventFd.clear(); - EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0); - EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0); -} - -TEST_F(BufferHubEventFdTest, EventFd_testTwoEventFds) { - BufferHubEventFd eventFd1; - BufferHubEventFd eventFd2; - - ASSERT_TRUE(eventFd1.isValid()); - ASSERT_TRUE(eventFd2.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}}; - epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}}; - - ASSERT_GE(epollFd.get(), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0); - - std::array<epoll_event, 2> events; - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - // Signal one by one. - eventFd1.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(events[0].data.u32, e1.data.u32); - - eventFd2.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); - EXPECT_EQ(events[0].data.u32, e2.data.u32); - - // Signal both. - eventFd1.signal(); - eventFd2.signal(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 2); - - uint32_t u32s[] = {events[0].data.u32, events[1].data.u32}; - EXPECT_THAT(u32s, Contains(e1.data.u32)); - EXPECT_THAT(u32s, Contains(e2.data.u32)); - - // The epoll fd is edge triggered, so it only responds to the eventFd once. - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0); - - eventFd1.signal(); - eventFd2.signal(); - eventFd2.clear(); - EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1); -} - -TEST_F(BufferHubEventFdTest, EventFd_testPollingThreadWithTwoEventFds) { - BufferHubEventFd eventFd1; - BufferHubEventFd eventFd2; - - ASSERT_TRUE(eventFd1.isValid()); - ASSERT_TRUE(eventFd2.isValid()); - - base::unique_fd epollFd(epoll_create(64)); - epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}}; - epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}}; - - ASSERT_GE(epollFd.get(), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0); - ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0); - - int countEvent1 = 0; - int countEvent2 = 0; - std::atomic<bool> stop{false}; - std::mutex mx; - std::condition_variable cv; - - std::thread pollingThread([&] { - std::array<epoll_event, 2> events; - while (true) { - if (stop.load()) { - break; - } - int ret = epoll_wait(epollFd.get(), events.data(), events.size(), kTimeout); - ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed."); - - std::lock_guard<std::mutex> lock(mx); - for (int i = 0; i < ret; i++) { - if (events[i].data.u32 == e1.data.u32) { - countEvent1++; - cv.notify_one(); - } else if (events[i].data.u32 == e2.data.u32) { - countEvent2++; - cv.notify_one(); - } - } - } - }); - - { - std::unique_lock<std::mutex> lock(mx); - - eventFd1.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 1; })); - - eventFd1.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 2; })); - - eventFd2.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 1; })); - - eventFd1.clear(); - eventFd2.clear(); - EXPECT_EQ(countEvent1, 2); - EXPECT_EQ(countEvent2, 1); - - eventFd1.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 3; })); - - eventFd2.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 2; })); - } - - stop.store(true); - pollingThread.join(); -} - -TEST_F(BufferHubEventFdTest, EventFd_testTwoPollingThreads) { - BufferHubEventFd eventFd; - ASSERT_TRUE(eventFd.isValid()); - - base::unique_fd epollFd1(epoll_create(64)); - base::unique_fd epollFd2(epoll_create(64)); - epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}}; - - ASSERT_GE(epollFd1.get(), 0); - ASSERT_GE(epollFd2.get(), 0); - - // Register the same eventFd to two EpollFds. - ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0); - - int countEpoll1 = 0; - int countEpoll2 = 0; - std::atomic<bool> stop{false}; - std::mutex mx; - std::condition_variable cv; - - std::thread pollingThread1([&] { - std::array<epoll_event, 1> events; - while (!stop.load()) { - int ret = epoll_wait(epollFd1.get(), events.data(), events.size(), kTimeout); - ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed."); - - if (ret > 0) { - std::lock_guard<std::mutex> lock(mx); - countEpoll1++; - cv.notify_one(); - } - } - }); - - std::thread pollingThread2([&] { - std::array<epoll_event, 1> events; - while (!stop.load()) { - int ret = epoll_wait(epollFd2.get(), events.data(), events.size(), kTimeout); - ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed."); - - if (ret > 0) { - std::lock_guard<std::mutex> lock(mx); - countEpoll2++; - cv.notify_one(); - } - } - }); - - { - std::unique_lock<std::mutex> lock(mx); - - eventFd.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 1; })); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 1; })); - - eventFd.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 2; })); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 2; })); - - eventFd.clear(); - EXPECT_EQ(countEpoll1, 2); - EXPECT_EQ(countEpoll2, 2); - - eventFd.signal(); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 3; })); - EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 3; })); - } - - stop.store(true); - pollingThread1.join(); - pollingThread2.join(); -} - -} // namespace android diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp deleted file mode 100644 index eb978cabc6..0000000000 --- a/libs/ui/tests/BufferHubMetadata_test.cpp +++ /dev/null @@ -1,98 +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. - */ - -#include <gtest/gtest.h> -#include <ui/BufferHubMetadata.h> - -namespace android { -namespace dvr { - -constexpr size_t kEmptyUserMetadataSize = 0; - -class BufferHubMetadataTest : public ::testing::Test {}; - -TEST_F(BufferHubMetadataTest, Create_UserMetdataSizeTooBig) { - BufferHubMetadata m1 = BufferHubMetadata::create(std::numeric_limits<uint32_t>::max()); - EXPECT_FALSE(m1.isValid()); -} - -TEST_F(BufferHubMetadataTest, Create_Success) { - BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize); - EXPECT_TRUE(m1.isValid()); - EXPECT_NE(m1.metadataHeader(), nullptr); -} - -TEST_F(BufferHubMetadataTest, Import_Success) { - BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize); - EXPECT_TRUE(m1.isValid()); - EXPECT_NE(m1.metadataHeader(), nullptr); - - unique_fd h2 = unique_fd(dup(m1.ashmemFd().get())); - EXPECT_NE(h2.get(), -1); - - BufferHubMetadata m2 = BufferHubMetadata::import(std::move(h2)); - EXPECT_EQ(h2.get(), -1); - EXPECT_TRUE(m1.isValid()); - BufferHubDefs::MetadataHeader* mh1 = m1.metadataHeader(); - EXPECT_NE(mh1, nullptr); - - // Check if the newly allocated buffer is initialized in released state (i.e. - // state equals to 0U). - EXPECT_TRUE(mh1->bufferState.load() == 0U); - - EXPECT_TRUE(m2.isValid()); - BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader(); - EXPECT_NE(mh2, nullptr); - - // Check if the newly allocated buffer is initialized in released state (i.e. - // state equals to 0U). - EXPECT_TRUE(mh2->bufferState.load() == 0U); -} - -TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) { - BufferHubMetadata m1 = BufferHubMetadata::create(sizeof(int)); - EXPECT_TRUE(m1.isValid()); - EXPECT_NE(m1.metadataHeader(), nullptr); - EXPECT_NE(m1.ashmemFd().get(), -1); - EXPECT_EQ(m1.userMetadataSize(), sizeof(int)); - - BufferHubMetadata m2 = std::move(m1); - - // After the move, the metadata header (a raw pointer) should be reset in the older buffer. - EXPECT_EQ(m1.metadataHeader(), nullptr); - EXPECT_NE(m2.metadataHeader(), nullptr); - - EXPECT_EQ(m1.ashmemFd().get(), -1); - EXPECT_NE(m2.ashmemFd().get(), -1); - - EXPECT_EQ(m1.userMetadataSize(), 0U); - EXPECT_EQ(m2.userMetadataSize(), sizeof(int)); - - BufferHubMetadata m3{std::move(m2)}; - - // After the move, the metadata header (a raw pointer) should be reset in the older buffer. - EXPECT_EQ(m2.metadataHeader(), nullptr); - EXPECT_NE(m3.metadataHeader(), nullptr); - - EXPECT_EQ(m2.ashmemFd().get(), -1); - EXPECT_NE(m3.ashmemFd().get(), -1); - - EXPECT_EQ(m2.userMetadataSize(), 0U); - EXPECT_EQ(m3.userMetadataSize(), sizeof(int)); -} - -} // namespace dvr -} // namespace android diff --git a/libs/ui/tests/GraphicBufferOverBinder_test.cpp b/libs/ui/tests/GraphicBufferOverBinder_test.cpp index 7c0a44a64f..126a945a0a 100644 --- a/libs/ui/tests/GraphicBufferOverBinder_test.cpp +++ b/libs/ui/tests/GraphicBufferOverBinder_test.cpp @@ -23,7 +23,6 @@ #include <gui/BufferQueue.h> #include <gui/IGraphicBufferConsumer.h> #include <gui/IGraphicBufferProducer.h> -#include <ui/BufferHubBuffer.h> #include <ui/GraphicBuffer.h> #include <utils/Log.h> @@ -37,7 +36,6 @@ constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN; static const String16 kTestServiceName = String16("GraphicBufferOverBinderTestService"); enum GraphicBufferOverBinderTestServiceCode { GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION, - GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER, }; class GraphicBufferOverBinderTestService : public BBinder { @@ -46,21 +44,6 @@ public: // GraphicBuffer mGraphicBuffer = new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount, kTestUsage); - ALOGI("mGraphicBuffer id %" PRIi32, mGraphicBuffer->getBufferId()); - - // BufferHub-backed GraphicBuffer - std::unique_ptr<BufferHubBuffer> bufferHubBuffer = - BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat, - kTestUsage, /*userMetadataSize=*/0); - mBufferhubBackedGraphicBuffer = new GraphicBuffer(std::move(bufferHubBuffer)); - if (!mBufferhubBackedGraphicBuffer->isBufferHubBuffer()) { - ALOGE("Failed to back GraphicBuffer with BufferHub."); - } - if (bufferHubBuffer != nullptr) { - ALOGE("Failed to move BufferHubBuffer to GraphicBuffer"); - } - ALOGI("mBufferhubBackedGraphicBuffer id %" PRIi32, - mBufferhubBackedGraphicBuffer->getBufferId()); } ~GraphicBufferOverBinderTestService() = default; @@ -71,9 +54,6 @@ public: case GRAPHIC_BUFFER: { return reply->write(*mGraphicBuffer); } - case GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER: { - return reply->write(*mBufferhubBackedGraphicBuffer); - } default: return UNKNOWN_TRANSACTION; }; @@ -81,7 +61,6 @@ public: protected: sp<GraphicBuffer> mGraphicBuffer; - sp<GraphicBuffer> mBufferhubBackedGraphicBuffer; }; static int runBinderServer() { @@ -138,17 +117,6 @@ TEST_F(GraphicBufferOverBinderTest, SendGraphicBufferOverBinder) { sp<GraphicBuffer> gb; EXPECT_EQ(GetGraphicBuffer(&gb, GRAPHIC_BUFFER), OK); EXPECT_NE(gb, nullptr); - EXPECT_FALSE(gb->isBufferHubBuffer()); - void* vaddr; - EXPECT_EQ(gb->lock(kTestUsage, &vaddr), OK); - EXPECT_EQ(gb->unlock(), OK); -} - -TEST_F(GraphicBufferOverBinderTest, SendGraphicBufferFromBufferHubBufferOverBinder) { - sp<GraphicBuffer> gb; - EXPECT_EQ(GetGraphicBuffer(&gb, GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER), NO_ERROR); - EXPECT_NE(gb, nullptr); - EXPECT_TRUE(gb->isBufferHubBuffer()); void* vaddr; EXPECT_EQ(gb->lock(kTestUsage, &vaddr), OK); EXPECT_EQ(gb->unlock(), OK); diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp index 5e0b094b7b..19551b3604 100644 --- a/libs/ui/tests/GraphicBuffer_test.cpp +++ b/libs/ui/tests/GraphicBuffer_test.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "GraphicBufferTest" -#include <ui/BufferHubBuffer.h> #include <ui/GraphicBuffer.h> #include <gtest/gtest.h> @@ -27,7 +26,6 @@ namespace { constexpr uint32_t kTestWidth = 1024; constexpr uint32_t kTestHeight = 1; -constexpr uint32_t kTestFormat = HAL_PIXEL_FORMAT_BLOB; constexpr uint32_t kTestLayerCount = 1; constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN; @@ -68,88 +66,4 @@ TEST_F(GraphicBufferTest, AllocateBadDimensions) { ASSERT_EQ(BAD_VALUE, gb2->initCheck()); } -TEST_F(GraphicBufferTest, CreateFromBufferHubBuffer) { - std::unique_ptr<BufferHubBuffer> b1 = - BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat, - kTestUsage, /*userMetadataSize=*/0); - ASSERT_NE(b1, nullptr); - EXPECT_TRUE(b1->isValid()); - - sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1))); - EXPECT_TRUE(gb->isBufferHubBuffer()); - - EXPECT_EQ(gb->getWidth(), kTestWidth); - EXPECT_EQ(gb->getHeight(), kTestHeight); - EXPECT_EQ(static_cast<uint32_t>(gb->getPixelFormat()), kTestFormat); - EXPECT_EQ(gb->getUsage(), kTestUsage); - EXPECT_EQ(gb->getLayerCount(), kTestLayerCount); -} - -TEST_F(GraphicBufferTest, InvalidBufferIdForNoneBufferHubBuffer) { - sp<GraphicBuffer> gb( - new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount, kTestUsage)); - EXPECT_FALSE(gb->isBufferHubBuffer()); - EXPECT_EQ(gb->getBufferId(), -1); -} - -TEST_F(GraphicBufferTest, BufferIdMatchesBufferHubBufferId) { - std::unique_ptr<BufferHubBuffer> b1 = - BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat, - kTestUsage, /*userMetadataSize=*/0); - EXPECT_NE(b1, nullptr); - EXPECT_TRUE(b1->isValid()); - - int b1_id = b1->id(); - EXPECT_GE(b1_id, 0); - - sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1))); - EXPECT_TRUE(gb->isBufferHubBuffer()); - EXPECT_EQ(gb->getBufferId(), b1_id); -} - -TEST_F(GraphicBufferTest, flattenAndUnflatten) { - std::unique_ptr<BufferHubBuffer> b1 = - BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat, - kTestUsage, /*userMetadataSize=*/0); - ASSERT_NE(b1, nullptr); - sp<GraphicBuffer> gb1(new GraphicBuffer(std::move(b1))); - gb1->setGenerationNumber(42); - - size_t flattenedSize = gb1->getFlattenedSize(); - EXPECT_EQ(flattenedSize, 48); - size_t fdCount = gb1->getFdCount(); - EXPECT_EQ(fdCount, 0); - - int data[flattenedSize]; - int fds[0]; - - // Make copies of needed items since flatten modifies them. - size_t flattenedSizeCopy = flattenedSize; - size_t fdCountCopy = fdCount; - void* dataStart = data; - int* fdsStart = fds; - status_t err = gb1->flatten(dataStart, flattenedSizeCopy, fdsStart, fdCountCopy); - ASSERT_EQ(err, NO_ERROR); - EXPECT_EQ(flattenedSizeCopy, 0); - EXPECT_EQ(fdCountCopy, 0); - - size_t unflattenSize = flattenedSize; - size_t unflattenFdCount = fdCount; - const void* unflattenData = static_cast<const void*>(dataStart); - const int* unflattenFdData = static_cast<const int*>(fdsStart); - - GraphicBuffer* gb2 = new GraphicBuffer(); - err = gb2->unflatten(unflattenData, unflattenSize, unflattenFdData, unflattenFdCount); - ASSERT_EQ(err, NO_ERROR); - EXPECT_TRUE(gb2->isBufferHubBuffer()); - - EXPECT_EQ(gb2->getWidth(), kTestWidth); - EXPECT_EQ(gb2->getHeight(), kTestHeight); - EXPECT_EQ(static_cast<uint32_t>(gb2->getPixelFormat()), kTestFormat); - EXPECT_EQ(gb2->getUsage(), kTestUsage); - EXPECT_EQ(gb2->getLayerCount(), kTestLayerCount); - EXPECT_EQ(gb1->getBufferId(), gb2->getBufferId()); - EXPECT_EQ(gb2->getGenerationNumber(), 42); -} - } // namespace android diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp deleted file mode 100644 index 2bb6aef3a5..0000000000 --- a/services/bufferhub/Android.bp +++ /dev/null @@ -1,77 +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. -// - -cc_library_shared { - name: "libbufferhubservice", - cflags: [ - "-DLOG_TAG=\"libbufferhubservice\"", - "-Wall", - "-Werror", - "-Wextra", - ], - srcs: [ - "BufferClient.cpp", - "BufferHubIdGenerator.cpp", - "BufferHubService.cpp", - "BufferNode.cpp", - ], - header_libs: [ - "libdvr_headers", - "libnativewindow_headers", - ], - shared_libs: [ - "android.frameworks.bufferhub@1.0", - "libcrypto", - "libcutils", - "libhidlbase", - "liblog", - "libui", - "libutils", - ], - export_include_dirs: [ - "include" - ], -} - -cc_binary { - name: "android.frameworks.bufferhub@1.0-service", - relative_install_path: "hw", - srcs: [ - "main_bufferhub.cpp" - ], - header_libs: [ - "libdvr_headers", - "libnativewindow_headers", - ], - shared_libs: [ - "android.frameworks.bufferhub@1.0", - "libbufferhubservice", - "libcrypto", - "libcutils", - "libhidlbase", - "liblog", - "libui", - "libutils", - ], - cflags: [ - "-DLOG_TAG=\"bufferhub\"", - "-Wall", - "-Werror", - "-Wextra", - ], - init_rc: ["android.frameworks.bufferhub@1.0-service.rc"], - vintf_fragments: ["android.frameworks.bufferhub@1.0-service.xml"], -} diff --git a/services/bufferhub/BufferClient.cpp b/services/bufferhub/BufferClient.cpp deleted file mode 100644 index ec7e535699..0000000000 --- a/services/bufferhub/BufferClient.cpp +++ /dev/null @@ -1,100 +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. - */ - -#include <bufferhub/BufferClient.h> -#include <bufferhub/BufferHubService.h> -#include <hidl/HidlSupport.h> -#include <log/log.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -using hardware::hidl_handle; -using hardware::Void; - -BufferClient* BufferClient::create(BufferHubService* service, - const std::shared_ptr<BufferNode>& node) { - if (!service) { - ALOGE("%s: service cannot be nullptr.", __FUNCTION__); - return nullptr; - } else if (!node) { - ALOGE("%s: node cannot be nullptr.", __FUNCTION__); - return nullptr; - } - return new BufferClient(service, node); -} - -BufferClient::~BufferClient() { - { - std::lock_guard<std::mutex> lock(mClosedMutex); - if (!mClosed) { - ALOGW("%s: client of buffer #%d destroyed without close. Closing it now.", __FUNCTION__, - mBufferNode->id()); - } - } - - close(); -} - -Return<BufferHubStatus> BufferClient::close() { - std::lock_guard<std::mutex> lock(mClosedMutex); - if (mClosed) { - return BufferHubStatus::CLIENT_CLOSED; - } - - getService()->onClientClosed(this); - mBufferNode.reset(); - mClosed = true; - return BufferHubStatus::NO_ERROR; -} - -Return<void> BufferClient::duplicate(duplicate_cb _hidl_cb) { - std::lock_guard<std::mutex> lock(mClosedMutex); - if (mClosed) { - _hidl_cb(/*token=*/hidl_handle(), /*status=*/BufferHubStatus::CLIENT_CLOSED); - return Void(); - } - - if (!mBufferNode) { - // Should never happen - ALOGE("%s: node is missing.", __FUNCTION__); - _hidl_cb(/*token=*/hidl_handle(), /*status=*/BufferHubStatus::BUFFER_FREED); - return Void(); - } - - const hidl_handle token = getService()->registerToken(this); - _hidl_cb(/*token=*/token, /*status=*/BufferHubStatus::NO_ERROR); - return Void(); -} - -sp<BufferHubService> BufferClient::getService() { - sp<BufferHubService> service = mService.promote(); - if (service == nullptr) { - // Should never happen. Kill the process. - LOG_FATAL("%s: service died.", __FUNCTION__); - } - - return service; -} - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android
\ No newline at end of file diff --git a/services/bufferhub/BufferHubIdGenerator.cpp b/services/bufferhub/BufferHubIdGenerator.cpp deleted file mode 100644 index 2c12f0e26d..0000000000 --- a/services/bufferhub/BufferHubIdGenerator.cpp +++ /dev/null @@ -1,59 +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. - */ - -#include <bufferhub/BufferHubIdGenerator.h> -#include <log/log.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -BufferHubIdGenerator& BufferHubIdGenerator::getInstance() { - static BufferHubIdGenerator generator; - - return generator; -} - -int BufferHubIdGenerator::getId() { - std::lock_guard<std::mutex> lock(mIdsInUseMutex); - - do { - if (++mLastId >= std::numeric_limits<int>::max()) { - mLastId = 0; - } - } while (mIdsInUse.find(mLastId) != mIdsInUse.end()); - - mIdsInUse.insert(mLastId); - return mLastId; -} - -void BufferHubIdGenerator::freeId(int id) { - std::lock_guard<std::mutex> lock(mIdsInUseMutex); - auto iter = mIdsInUse.find(id); - if (iter != mIdsInUse.end()) { - mIdsInUse.erase(iter); - } else { - ALOGW("%s: Cannot free nonexistent id #%d", __FUNCTION__, id); - } -} - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp deleted file mode 100644 index 7a3472fa7e..0000000000 --- a/services/bufferhub/BufferHubService.cpp +++ /dev/null @@ -1,401 +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. - */ - -#include <array> -#include <iomanip> -#include <random> -#include <sstream> - -#include <android/hardware_buffer.h> -#include <bufferhub/BufferHubService.h> -#include <cutils/native_handle.h> -#include <log/log.h> -#include <openssl/hmac.h> -#include <system/graphics-base.h> -#include <ui/BufferHubDefs.h> - -using ::android::BufferHubDefs::MetadataHeader; -using ::android::hardware::Void; - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -BufferHubService::BufferHubService() { - std::mt19937_64 randomEngine; - randomEngine.seed(time(nullptr)); - - mKey = randomEngine(); -} - -Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description, - const uint32_t userMetadataSize, - allocateBuffer_cb _hidl_cb) { - AHardwareBuffer_Desc desc; - memcpy(&desc, &description, sizeof(AHardwareBuffer_Desc)); - - std::shared_ptr<BufferNode> node = - std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format, - desc.usage, userMetadataSize, - BufferHubIdGenerator::getInstance().getId()); - if (node == nullptr || !node->isValid()) { - ALOGE("%s: creating BufferNode failed.", __FUNCTION__); - _hidl_cb(/*status=*/BufferHubStatus::ALLOCATION_FAILED, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - sp<BufferClient> client = BufferClient::create(this, node); - // Add it to list for bookkeeping and dumpsys. - std::lock_guard<std::mutex> lock(mClientSetMutex); - mClientSet.emplace(client); - - // Allocate memory for bufferInfo of type hidl_handle on the stack. See - // http://aosp/286282 for the usage of NATIVE_HANDLE_DECLARE_STORAGE. - NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds, - BufferHubDefs::kBufferInfoNumInts); - hidl_handle bufferInfo = - buildBufferInfo(bufferInfoStorage, node->id(), node->addNewActiveClientsBitToMask(), - node->userMetadataSize(), node->metadata().ashmemFd(), - node->eventFd().get()); - // During the gralloc allocation carried out by BufferNode, gralloc allocator will populate the - // fields of its HardwareBufferDescription (i.e. strides) according to the actual - // gralloc implementation. We need to read those fields back and send them to the client via - // BufferTraits. - HardwareBufferDescription allocatedBufferDesc; - memcpy(&allocatedBufferDesc, &node->bufferDesc(), sizeof(AHardwareBuffer_Desc)); - BufferTraits bufferTraits = {/*bufferDesc=*/allocatedBufferDesc, - /*bufferHandle=*/hidl_handle(node->bufferHandle()), - /*bufferInfo=*/std::move(bufferInfo)}; - - _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client, - /*bufferTraits=*/std::move(bufferTraits)); - return Void(); -} - -Return<void> BufferHubService::importBuffer(const hidl_handle& tokenHandle, - importBuffer_cb _hidl_cb) { - if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts <= 1) { - // nullptr handle or wrong format - _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - int tokenId = tokenHandle->data[0]; - - wp<BufferClient> originClientWp; - { - std::lock_guard<std::mutex> lock(mTokenMutex); - auto iter = mTokenMap.find(tokenId); - if (iter == mTokenMap.end()) { - // Token Id not exist - ALOGD("%s: token #%d not found.", __FUNCTION__, tokenId); - _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - const std::vector<uint8_t>& tokenHMAC = iter->second.first; - - int numIntsForHMAC = (int)ceil(tokenHMAC.size() * sizeof(uint8_t) / (double)sizeof(int)); - if (tokenHandle->numInts - 1 != numIntsForHMAC) { - // HMAC size not match - ALOGD("%s: token #%d HMAC size not match. Expected: %d Actual: %d", __FUNCTION__, - tokenId, numIntsForHMAC, tokenHandle->numInts - 1); - _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - size_t hmacSize = tokenHMAC.size() * sizeof(uint8_t); - if (memcmp(tokenHMAC.data(), &tokenHandle->data[1], hmacSize) != 0) { - // HMAC not match - ALOGD("%s: token #%d HMAC not match.", __FUNCTION__, tokenId); - _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - originClientWp = iter->second.second; - mTokenMap.erase(iter); - } - - // Check if original client is dead - sp<BufferClient> originClient = originClientWp.promote(); - if (!originClient) { - // Should not happen since token should be removed if already gone - ALOGE("%s: original client %p gone!", __FUNCTION__, originClientWp.unsafe_get()); - _hidl_cb(/*status=*/BufferHubStatus::BUFFER_FREED, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - sp<BufferClient> client = new BufferClient(*originClient); - uint32_t clientStateMask = client->getBufferNode()->addNewActiveClientsBitToMask(); - if (clientStateMask == 0U) { - // Reach max client count - ALOGE("%s: import failed, BufferNode#%u reached maximum clients.", __FUNCTION__, - client->getBufferNode()->id()); - _hidl_cb(/*status=*/BufferHubStatus::MAX_CLIENT, /*bufferClient=*/nullptr, - /*bufferTraits=*/{}); - return Void(); - } - - std::lock_guard<std::mutex> lock(mClientSetMutex); - mClientSet.emplace(client); - - std::shared_ptr<BufferNode> node = client->getBufferNode(); - - HardwareBufferDescription bufferDesc; - memcpy(&bufferDesc, &node->bufferDesc(), sizeof(HardwareBufferDescription)); - - // Allocate memory for bufferInfo of type hidl_handle on the stack. See - // http://aosp/286282 for the usage of NATIVE_HANDLE_DECLARE_STORAGE. - NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds, - BufferHubDefs::kBufferInfoNumInts); - hidl_handle bufferInfo = buildBufferInfo(bufferInfoStorage, node->id(), clientStateMask, - node->userMetadataSize(), node->metadata().ashmemFd(), - node->eventFd().get()); - BufferTraits bufferTraits = {/*bufferDesc=*/bufferDesc, - /*bufferHandle=*/hidl_handle(node->bufferHandle()), - /*bufferInfo=*/std::move(bufferInfo)}; - - _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client, - /*bufferTraits=*/std::move(bufferTraits)); - return Void(); -} - -Return<void> BufferHubService::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) { - if (fd.getNativeHandle() == nullptr || fd->numFds < 1) { - ALOGE("%s: missing fd for writing.", __FUNCTION__); - return Void(); - } - - FILE* out = fdopen(dup(fd->data[0]), "w"); - - if (args.size() != 0) { - fprintf(out, - "Note: lshal bufferhub currently does not support args. Input arguments are " - "ignored.\n"); - } - - std::ostringstream stream; - - // Get the number of clients of each buffer. - // Map from bufferId to bufferNode_clientCount pair. - std::map<int, std::pair<const std::shared_ptr<BufferNode>, uint32_t>> clientCount; - { - std::lock_guard<std::mutex> lock(mClientSetMutex); - for (auto iter = mClientSet.begin(); iter != mClientSet.end(); ++iter) { - sp<BufferClient> client = iter->promote(); - if (client != nullptr) { - const std::shared_ptr<BufferNode> node = client->getBufferNode(); - auto mapIter = clientCount.find(node->id()); - if (mapIter != clientCount.end()) { - ++mapIter->second.second; - } else { - clientCount.emplace(node->id(), - std::pair<std::shared_ptr<BufferNode>, uint32_t>(node, 1U)); - } - } - } - } - - stream << "Active Buffers:\n"; - stream << std::right; - stream << std::setw(6) << "Id"; - stream << " "; - stream << std::setw(9) << "#Clients"; - stream << " "; - stream << std::setw(14) << "Geometry"; - stream << " "; - stream << std::setw(6) << "Format"; - stream << " "; - stream << std::setw(10) << "Usage"; - stream << " "; - stream << std::setw(10) << "State"; - stream << " "; - stream << std::setw(8) << "Index"; - stream << std::endl; - - for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) { - const std::shared_ptr<BufferNode> node = std::move(iter->second.first); - const uint32_t clientCount = iter->second.second; - AHardwareBuffer_Desc desc = node->bufferDesc(); - - MetadataHeader* metadataHeader = - const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader(); - const uint32_t state = metadataHeader->bufferState.load(std::memory_order_acquire); - const uint64_t index = metadataHeader->queueIndex; - - stream << std::right; - stream << std::setw(6) << /*Id=*/node->id(); - stream << " "; - stream << std::setw(9) << /*#Clients=*/clientCount; - stream << " "; - if (desc.format == HAL_PIXEL_FORMAT_BLOB) { - std::string size = std::to_string(desc.width) + " B"; - stream << std::setw(14) << /*Geometry=*/size; - } else { - std::string dimensions = std::to_string(desc.width) + "x" + - std::to_string(desc.height) + "x" + std::to_string(desc.layers); - stream << std::setw(14) << /*Geometry=*/dimensions; - } - stream << " "; - stream << std::setw(6) << /*Format=*/desc.format; - stream << " "; - stream << "0x" << std::hex << std::setfill('0'); - stream << std::setw(8) << /*Usage=*/desc.usage; - stream << std::dec << std::setfill(' '); - stream << " "; - stream << "0x" << std::hex << std::setfill('0'); - stream << std::setw(8) << /*State=*/state; - stream << std::dec << std::setfill(' '); - stream << " "; - stream << std::setw(8) << /*Index=*/index; - stream << std::endl; - } - - stream << std::endl; - - // Get the number of tokens of each buffer. - // Map from bufferId to tokenCount - std::map<int, uint32_t> tokenCount; - { - std::lock_guard<std::mutex> lock(mTokenMutex); - for (auto iter = mTokenMap.begin(); iter != mTokenMap.end(); ++iter) { - sp<BufferClient> client = iter->second.second.promote(); - if (client != nullptr) { - const std::shared_ptr<BufferNode> node = client->getBufferNode(); - auto mapIter = tokenCount.find(node->id()); - if (mapIter != tokenCount.end()) { - ++mapIter->second; - } else { - tokenCount.emplace(node->id(), 1U); - } - } - } - } - - stream << "Unused Tokens:\n"; - stream << std::right; - stream << std::setw(8) << "Buffer Id"; - stream << " "; - stream << std::setw(7) << "#Tokens"; - stream << std::endl; - - for (auto iter = tokenCount.begin(); iter != tokenCount.end(); ++iter) { - stream << std::right; - stream << std::setw(8) << /*Buffer Id=*/iter->first; - stream << " "; - stream << std::setw(7) << /*#Tokens=*/iter->second; - stream << std::endl; - } - - fprintf(out, "%s", stream.str().c_str()); - - fclose(out); - return Void(); -} - -hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) { - // Find next available token id - std::lock_guard<std::mutex> lock(mTokenMutex); - do { - ++mLastTokenId; - } while (mTokenMap.find(mLastTokenId) != mTokenMap.end()); - - std::array<uint8_t, EVP_MAX_MD_SIZE> hmac; - uint32_t hmacSize = 0U; - - HMAC(/*evp_md=*/EVP_sha256(), /*key=*/&mKey, /*key_len=*/kKeyLen, - /*data=*/(uint8_t*)&mLastTokenId, /*data_len=*/mTokenIdSize, - /*out=*/hmac.data(), /*out_len=*/&hmacSize); - - int numIntsForHMAC = (int)ceil(hmacSize / (double)sizeof(int)); - native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1 + numIntsForHMAC); - handle->data[0] = mLastTokenId; - // Set all the the bits of last int to 0 since it might not be fully overwritten - handle->data[numIntsForHMAC] = 0; - memcpy(&handle->data[1], hmac.data(), hmacSize); - - // returnToken owns the native_handle_t* thus doing lifecycle management - hidl_handle returnToken; - returnToken.setTo(handle, /*shoudOwn=*/true); - - std::vector<uint8_t> hmacVec; - hmacVec.resize(hmacSize); - memcpy(hmacVec.data(), hmac.data(), hmacSize); - mTokenMap.emplace(mLastTokenId, std::pair(hmacVec, client)); - - return returnToken; -} - -void BufferHubService::onClientClosed(const BufferClient* client) { - removeTokenByClient(client); - - std::lock_guard<std::mutex> lock(mClientSetMutex); - auto iter = std::find(mClientSet.begin(), mClientSet.end(), client); - if (iter != mClientSet.end()) { - mClientSet.erase(iter); - } -} - -// Implementation of this function should be consistent with the definition of bufferInfo handle in -// ui/BufferHubDefs.h. -hidl_handle BufferHubService::buildBufferInfo(char* bufferInfoStorage, int bufferId, - uint32_t clientBitMask, uint32_t userMetadataSize, - int metadataFd, int eventFd) { - native_handle_t* infoHandle = - native_handle_init(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds, - BufferHubDefs::kBufferInfoNumInts); - - infoHandle->data[0] = metadataFd; - infoHandle->data[1] = eventFd; - infoHandle->data[2] = bufferId; - // Use memcpy to convert to int without missing digit. - // TOOD(b/121345852): use bit_cast to unpack bufferInfo when C++20 becomes available. - memcpy(&infoHandle->data[3], &clientBitMask, sizeof(clientBitMask)); - memcpy(&infoHandle->data[4], &userMetadataSize, sizeof(userMetadataSize)); - - hidl_handle bufferInfo; - bufferInfo.setTo(infoHandle, /*shouldOwn=*/false); - - return bufferInfo; -} - -void BufferHubService::removeTokenByClient(const BufferClient* client) { - std::lock_guard<std::mutex> lock(mTokenMutex); - auto iter = mTokenMap.begin(); - while (iter != mTokenMap.end()) { - if (iter->second.second == client) { - auto oldIter = iter; - ++iter; - mTokenMap.erase(oldIter); - } else { - ++iter; - } - } -} - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp deleted file mode 100644 index 04ca6493f7..0000000000 --- a/services/bufferhub/BufferNode.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include <errno.h> - -#include <bufferhub/BufferHubService.h> -#include <bufferhub/BufferNode.h> -#include <log/log.h> -#include <ui/GraphicBufferAllocator.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -void BufferNode::initializeMetadata() { - // Using placement new here to reuse shared memory instead of new allocation - // Initialize the atomic variables to zero. - BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader(); - mBufferState = new (&metadataHeader->bufferState) std::atomic<uint32_t>(0); - mFenceState = new (&metadataHeader->fenceState) std::atomic<uint32_t>(0); - mActiveClientsBitMask = new (&metadataHeader->activeClientsBitMask) std::atomic<uint32_t>(0); - // The C++ standard recommends (but does not require) that lock-free atomic operations are - // also address-free, that is, suitable for communication between processes using shared - // memory. - LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) || - !std::atomic_is_lock_free(mFenceState) || - !std::atomic_is_lock_free(mActiveClientsBitMask), - "Atomic variables in ashmen are not lock free."); -} - -// Allocates a new BufferNode. -BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format, - uint64_t usage, size_t userMetadataSize, int id) - : mId(id) { - uint32_t outStride = 0; - // graphicBufferId is not used in GraphicBufferAllocator::allocate - // TODO(b/112338294) After move to the service folder, stop using the - // hardcoded service name "bufferhub". - int ret = GraphicBufferAllocator::get().allocate(width, height, format, layerCount, usage, - const_cast<const native_handle_t**>( - &mBufferHandle), - &outStride, - /*graphicBufferId=*/0, - /*requestor=*/"bufferhub"); - - if (ret != OK || mBufferHandle == nullptr) { - ALOGE("%s: Failed to allocate buffer: %s", __FUNCTION__, strerror(-ret)); - return; - } - - mBufferDesc.width = width; - mBufferDesc.height = height; - mBufferDesc.layers = layerCount; - mBufferDesc.format = format; - mBufferDesc.usage = usage; - mBufferDesc.stride = outStride; - - mMetadata = BufferHubMetadata::create(userMetadataSize); - if (!mMetadata.isValid()) { - ALOGE("%s: Failed to allocate metadata.", __FUNCTION__); - return; - } - initializeMetadata(); -} - -BufferNode::~BufferNode() { - // Free the handle - if (mBufferHandle != nullptr) { - status_t ret = GraphicBufferAllocator::get().free(mBufferHandle); - if (ret != OK) { - ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret); - } - } - - // Free the id, if valid - if (mId >= 0) { - BufferHubIdGenerator::getInstance().freeId(mId); - } -} - -uint32_t BufferNode::getActiveClientsBitMask() const { - return mActiveClientsBitMask->load(std::memory_order_acquire); -} - -uint32_t BufferNode::addNewActiveClientsBitToMask() { - uint32_t currentActiveClientsBitMask = getActiveClientsBitMask(); - uint32_t clientStateMask = 0U; - uint32_t updatedActiveClientsBitMask = 0U; - do { - clientStateMask = - BufferHubDefs::findNextAvailableClientStateMask(currentActiveClientsBitMask); - if (clientStateMask == 0U) { - ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__, - BufferHubDefs::kMaxNumberOfClients); - errno = E2BIG; - return 0U; - } - updatedActiveClientsBitMask = currentActiveClientsBitMask | clientStateMask; - } while (!(mActiveClientsBitMask->compare_exchange_weak(currentActiveClientsBitMask, - updatedActiveClientsBitMask, - std::memory_order_acq_rel, - std::memory_order_acquire))); - return clientStateMask; -} - -void BufferNode::removeClientsBitFromMask(const uint32_t& value) { - mActiveClientsBitMask->fetch_and(~value); -} - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android diff --git a/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc b/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc deleted file mode 100644 index 36fbedee15..0000000000 --- a/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc +++ /dev/null @@ -1,6 +0,0 @@ -service system_bufferhub /system/bin/hw/android.frameworks.bufferhub@1.0-service - class hal animation - user system - group system graphics - onrestart restart surfaceflinger - writepid /dev/cpuset/system-background/tasks diff --git a/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml b/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml deleted file mode 100644 index bd958d3954..0000000000 --- a/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml +++ /dev/null @@ -1,11 +0,0 @@ -<manifest version="1.0" type="framework"> - <hal> - <name>android.frameworks.bufferhub</name> - <transport>hwbinder</transport> - <version>1.0</version> - <interface> - <name>IBufferHub</name> - <instance>default</instance> - </interface> - </hal> -</manifest> diff --git a/services/bufferhub/include/bufferhub/BufferClient.h b/services/bufferhub/include/bufferhub/BufferClient.h deleted file mode 100644 index 644b40377d..0000000000 --- a/services/bufferhub/include/bufferhub/BufferClient.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_CLIENT_H -#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_CLIENT_H - -#include <mutex> - -#include <android/frameworks/bufferhub/1.0/IBufferClient.h> -#include <bufferhub/BufferNode.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -using hardware::hidl_handle; -using hardware::Return; - -// Forward declaration to avoid circular dependency -class BufferHubService; - -class BufferClient : public IBufferClient { -public: - // Creates a server-side buffer client from an existing BufferNode. Note that - // this function takes ownership of the shared_ptr. - // Returns a raw pointer to the BufferClient on success, nullptr on failure. - static BufferClient* create(BufferHubService* service, const std::shared_ptr<BufferNode>& node); - - // Creates a BufferClient from an existing BufferClient. Will share the same BufferNode. - explicit BufferClient(const BufferClient& other) - : mService(other.mService), mBufferNode(other.mBufferNode) {} - ~BufferClient(); - - Return<BufferHubStatus> close() override; - Return<void> duplicate(duplicate_cb _hidl_cb) override; - - // Non-binder functions - const std::shared_ptr<BufferNode>& getBufferNode() const { return mBufferNode; } - -private: - BufferClient(wp<BufferHubService> service, const std::shared_ptr<BufferNode>& node) - : mService(service), mBufferNode(node) {} - - sp<BufferHubService> getService(); - - wp<BufferHubService> mService; - - std::mutex mClosedMutex; - bool mClosed GUARDED_BY(mClosedMutex) = false; - - std::shared_ptr<BufferNode> mBufferNode; -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android - -#endif diff --git a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h deleted file mode 100644 index ef7c077feb..0000000000 --- a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H -#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H - -#include <mutex> -#include <set> - -#include <utils/Mutex.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -// A thread-safe, non-negative, incremental, int id generator. -class BufferHubIdGenerator { -public: - // Get the singleton instance of this class - static BufferHubIdGenerator& getInstance(); - - // Gets next available id. If next id is greater than std::numeric_limits<int32_t>::max(), it - // will try to get an id start from 0 again. - int getId(); - - // Free a specific id. - void freeId(int id); - -private: - BufferHubIdGenerator() = default; - ~BufferHubIdGenerator() = default; - - // Start from -1 so all valid ids will be >= 0 - int mLastId = -1; - - std::mutex mIdsInUseMutex; - std::set<int> mIdsInUse GUARDED_BY(mIdsInUseMutex); -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android - -#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h deleted file mode 100644 index edad20b194..0000000000 --- a/services/bufferhub/include/bufferhub/BufferHubService.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H -#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H - -#include <map> -#include <mutex> -#include <set> -#include <vector> - -#include <android/frameworks/bufferhub/1.0/IBufferHub.h> -#include <bufferhub/BufferClient.h> -#include <bufferhub/BufferHubIdGenerator.h> -#include <utils/Mutex.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -using hardware::hidl_handle; -using hardware::hidl_string; -using hardware::hidl_vec; -using hardware::Return; -using hardware::graphics::common::V1_2::HardwareBufferDescription; - -class BufferHubService : public IBufferHub { -public: - BufferHubService(); - - Return<void> allocateBuffer(const HardwareBufferDescription& description, - const uint32_t userMetadataSize, - allocateBuffer_cb _hidl_cb) override; - Return<void> importBuffer(const hidl_handle& tokenHandle, importBuffer_cb _hidl_cb) override; - - Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override; - - // Non-binder functions - // Internal help function for IBufferClient::duplicate. - hidl_handle registerToken(const wp<BufferClient>& client); - - void onClientClosed(const BufferClient* client); - -private: - // Helper function to build BufferTraits.bufferInfo handle - hidl_handle buildBufferInfo(char* bufferInfoStorage, int bufferId, uint32_t clientBitMask, - uint32_t userMetadataSize, int metadataFd, int eventFd); - - // Helper function to remove all the token belongs to a specific client. - void removeTokenByClient(const BufferClient* client); - - // List of active BufferClient for bookkeeping. - std::mutex mClientSetMutex; - std::set<wp<BufferClient>> mClientSet GUARDED_BY(mClientSetMutex); - - // Token generation related - // A random number used as private key for HMAC - uint64_t mKey; - static constexpr size_t kKeyLen = sizeof(uint64_t); - - std::mutex mTokenMutex; - // The first TokenId will be 1. TokenId could be negative. - int mLastTokenId GUARDED_BY(mTokenMutex) = 0; - static constexpr size_t mTokenIdSize = sizeof(int); - // A map from token id to the token-buffer_client pair. Using token id as the key to reduce - // looking up time - std::map<int, std::pair<std::vector<uint8_t>, const wp<BufferClient>>> mTokenMap - GUARDED_BY(mTokenMutex); -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android - -#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h deleted file mode 100644 index 62a8d63b38..0000000000 --- a/services/bufferhub/include/bufferhub/BufferNode.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_ -#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_ - -#include <android/hardware_buffer.h> -#include <bufferhub/BufferHubIdGenerator.h> -#include <cutils/native_handle.h> -#include <ui/BufferHubEventFd.h> -#include <ui/BufferHubMetadata.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -class BufferNode { -public: - // Allocates a new BufferNode. - BufferNode(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format, - uint64_t usage, size_t userMetadataSize, int id = -1); - - ~BufferNode(); - - // Returns whether the object holds a valid metadata. - bool isValid() const { return mMetadata.isValid(); } - - int id() const { return mId; } - - size_t userMetadataSize() const { return mMetadata.userMetadataSize(); } - - // Accessors of the buffer description and handle - const native_handle_t* bufferHandle() const { return mBufferHandle; } - const AHardwareBuffer_Desc& bufferDesc() const { return mBufferDesc; } - - // Accessor of event fd. - const BufferHubEventFd& eventFd() const { return mEventFd; } - - // Accessors of mMetadata. - const BufferHubMetadata& metadata() const { return mMetadata; } - - // Gets the current value of mActiveClientsBitMask in mMetadata with - // std::memory_order_acquire, so that all previous releases of - // mActiveClientsBitMask from all threads will be returned here. - uint32_t getActiveClientsBitMask() const; - - // Find and add a new client state mask to mActiveClientsBitMask in - // mMetadata. - // Return the new client state mask that is added to mActiveClientsBitMask. - // Return 0U if there are already 16 clients of the buffer. - uint32_t addNewActiveClientsBitToMask(); - - // Removes the value from active_clients_bit_mask in mMetadata with - // std::memory_order_release, so that the change will be visible to any - // acquire of mActiveClientsBitMask in any threads after the succeed of - // this operation. - void removeClientsBitFromMask(const uint32_t& value); - -private: - // Helper method for constructors to initialize atomic metadata header - // variables in shared memory. - void initializeMetadata(); - - // Gralloc buffer handles. - native_handle_t* mBufferHandle; - AHardwareBuffer_Desc mBufferDesc; - - // Eventfd used for signalling buffer events among the clients of the buffer. - BufferHubEventFd mEventFd; - - // Metadata in shared memory. - BufferHubMetadata mMetadata; - - // A system-unique id generated by bufferhub from 0 to std::numeric_limits<int>::max(). - // BufferNodes not created by bufferhub will have id < 0, meaning "not specified". - // TODO(b/118891412): remove default id = -1 and update comments after pdx is no longer in use - const int mId = -1; - - // The following variables are atomic variables in mMetadata that are visible - // to Bn object and Bp objects. Please find more info in - // BufferHubDefs::MetadataHeader. - - // mBufferState tracks the state of the buffer. Buffer can be in one of these - // four states: gained, posted, acquired, released. - std::atomic<uint32_t>* mBufferState = nullptr; - - // TODO(b/112012161): add comments to mFenceState. - std::atomic<uint32_t>* mFenceState = nullptr; - - // mActiveClientsBitMask tracks all the bp clients of the buffer. It is the - // union of all client_state_mask of all bp clients. - std::atomic<uint32_t>* mActiveClientsBitMask = nullptr; -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android - -#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_ diff --git a/services/bufferhub/main_bufferhub.cpp b/services/bufferhub/main_bufferhub.cpp deleted file mode 100644 index 084460d993..0000000000 --- a/services/bufferhub/main_bufferhub.cpp +++ /dev/null @@ -1,37 +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. - */ - -#include <bufferhub/BufferHubService.h> -#include <hidl/HidlTransportSupport.h> -#include <hwbinder/IPCThreadState.h> -#include <log/log.h> - -using android::sp; -using android::frameworks::bufferhub::V1_0::IBufferHub; -using android::frameworks::bufferhub::V1_0::implementation::BufferHubService; - -int main(int /*argc*/, char** /*argv*/) { - ALOGI("Bootstrap bufferhub HIDL service."); - - android::hardware::configureRpcThreadpool(/*numThreads=*/1, /*willJoin=*/true); - - sp<IBufferHub> service = new BufferHubService(); - LOG_ALWAYS_FATAL_IF(service->registerAsService() != android::OK, "Failed to register service"); - - android::hardware::joinRpcThreadpool(); - - return 0; -} diff --git a/services/bufferhub/tests/Android.bp b/services/bufferhub/tests/Android.bp deleted file mode 100644 index 3033e705a9..0000000000 --- a/services/bufferhub/tests/Android.bp +++ /dev/null @@ -1,26 +0,0 @@ -cc_test { - name: "BufferHubServer_test", - srcs: [ - "BufferNode_test.cpp", - "BufferHubIdGenerator_test.cpp", - ], - cflags: [ - "-DLOG_TAG=\"BufferHubServer_test\"", - "-DTRACE=0", - "-DATRACE_TAG=ATRACE_TAG_GRAPHICS", - "-Wall", - "-Werror", - ], - compile_multilib: "first", - header_libs: [ - "libdvr_headers", - "libnativewindow_headers", - ], - shared_libs: [ - "libbufferhubservice", - "libui", - ], - static_libs: [ - "libgmock", - ], -} diff --git a/services/bufferhub/tests/BufferHubIdGenerator_test.cpp b/services/bufferhub/tests/BufferHubIdGenerator_test.cpp deleted file mode 100644 index fb6de0d18e..0000000000 --- a/services/bufferhub/tests/BufferHubIdGenerator_test.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include <bufferhub/BufferHubIdGenerator.h> -#include <gtest/gtest.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -namespace { - -class BufferHubIdGeneratorTest : public testing::Test { -protected: - BufferHubIdGenerator* mIdGenerator = &BufferHubIdGenerator::getInstance(); -}; - -TEST_F(BufferHubIdGeneratorTest, TestGenerateAndFreeID) { - int id = mIdGenerator->getId(); - EXPECT_GE(id, 0); - - mIdGenerator->freeId(id); -} - -TEST_F(BufferHubIdGeneratorTest, TestGenerateUniqueIncrementalID) { - // 10 IDs should not overflow the UniqueIdGenerator to cause a roll back to start, so the - // resulting IDs should still keep incresing. - const int kTestSize = 10; - int ids[kTestSize]; - for (int i = 0; i < kTestSize; ++i) { - ids[i] = mIdGenerator->getId(); - EXPECT_GE(ids[i], 0); - if (i >= 1) { - EXPECT_GT(ids[i], ids[i - 1]); - } - } - - for (int i = 0; i < kTestSize; ++i) { - mIdGenerator->freeId(ids[i]); - } -} - -} // namespace - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android
\ No newline at end of file diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp deleted file mode 100644 index 2dfd4fc52e..0000000000 --- a/services/bufferhub/tests/BufferNode_test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include <errno.h> - -#include <bufferhub/BufferNode.h> -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <ui/BufferHubDefs.h> -#include <ui/GraphicBufferMapper.h> - -namespace android { -namespace frameworks { -namespace bufferhub { -namespace V1_0 { -namespace implementation { - -namespace { - -using testing::NotNull; - -const uint32_t kWidth = 640; -const uint32_t kHeight = 480; -const uint32_t kLayerCount = 1; -const uint32_t kFormat = 1; -const uint64_t kUsage = 0; -const size_t kUserMetadataSize = 0; - -class BufferNodeTest : public ::testing::Test { -protected: - void SetUp() override { - mBufferNode = - new BufferNode(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize); - ASSERT_TRUE(mBufferNode->isValid()); - } - - void TearDown() override { - if (mBufferNode != nullptr) { - delete mBufferNode; - } - } - - BufferNode* mBufferNode = nullptr; -}; - -TEST_F(BufferNodeTest, TestCreateBufferNode) { - EXPECT_EQ(mBufferNode->userMetadataSize(), kUserMetadataSize); - // Test the handle just allocated is good (i.e. able to be imported) - GraphicBufferMapper& mapper = GraphicBufferMapper::get(); - const native_handle_t* outHandle; - status_t ret = - mapper.importBuffer(mBufferNode->bufferHandle(), mBufferNode->bufferDesc().width, - mBufferNode->bufferDesc().height, mBufferNode->bufferDesc().layers, - mBufferNode->bufferDesc().format, mBufferNode->bufferDesc().usage, - mBufferNode->bufferDesc().stride, &outHandle); - EXPECT_EQ(ret, OK); - EXPECT_THAT(outHandle, NotNull()); -} - -TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_twoNewClients) { - uint32_t newClientStateMask1 = mBufferNode->addNewActiveClientsBitToMask(); - EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), newClientStateMask1); - - // Request and add a new client_state_mask again. - // Active clients bit mask should be the union of the two new - // client_state_masks. - uint32_t newClientStateMask2 = mBufferNode->addNewActiveClientsBitToMask(); - EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), newClientStateMask1 | newClientStateMask2); -} - -TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_32NewClients) { - uint32_t newClientStateMask = 0U; - uint32_t currentMask = 0U; - uint32_t expectedMask = 0U; - - for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) { - newClientStateMask = mBufferNode->addNewActiveClientsBitToMask(); - EXPECT_NE(newClientStateMask, 0U); - EXPECT_FALSE(newClientStateMask & currentMask); - expectedMask = currentMask | newClientStateMask; - currentMask = mBufferNode->getActiveClientsBitMask(); - EXPECT_EQ(currentMask, expectedMask); - } - - // Method should fail upon requesting for more than maximum allowable clients. - newClientStateMask = mBufferNode->addNewActiveClientsBitToMask(); - EXPECT_EQ(newClientStateMask, 0U); - EXPECT_EQ(errno, E2BIG); -} - -TEST_F(BufferNodeTest, TestRemoveActiveClientsBitFromMask) { - mBufferNode->addNewActiveClientsBitToMask(); - uint32_t currentMask = mBufferNode->getActiveClientsBitMask(); - uint32_t newClientStateMask = mBufferNode->addNewActiveClientsBitToMask(); - EXPECT_NE(mBufferNode->getActiveClientsBitMask(), currentMask); - - mBufferNode->removeClientsBitFromMask(newClientStateMask); - EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), currentMask); - - // Remove the test_mask again to the active client bit mask should not modify - // the value of active clients bit mask. - mBufferNode->removeClientsBitFromMask(newClientStateMask); - EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), currentMask); -} - -} // namespace - -} // namespace implementation -} // namespace V1_0 -} // namespace bufferhub -} // namespace frameworks -} // namespace android |