Loading graphics/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ subdirs = [ "allocator/2.0", "allocator/2.0/default", "allocator/2.0/vts/functional", "common/1.0", "composer/2.1", "composer/2.1/default", Loading graphics/allocator/2.0/IAllocator.hal +15 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,9 @@ interface IAllocator { * * @return capabilities is a list of supported capabilities. */ @entry @exit @callflow(next="*") getCapabilities() generates (vec<Capability> capabilities); /* Loading @@ -86,6 +89,9 @@ interface IAllocator { * * @return debugInfo is a string of debug information. */ @entry @exit @callflow(next="*") dumpDebugInfo() generates (string debugInfo); /* Loading @@ -98,6 +104,8 @@ interface IAllocator { * NO_RESOURCES when no more descriptors can currently be created. * @return descriptor is the newly created buffer descriptor. */ @entry @callflow(next="*") createDescriptor(BufferDescriptorInfo descriptorInfo) generates (Error error, BufferDescriptor descriptor); Loading @@ -108,6 +116,8 @@ interface IAllocator { * @param descriptor is the descriptor to destroy. * @return error is either NONE or BAD_DESCRIPTOR. */ @exit @callflow(next="*") destroyDescriptor(BufferDescriptor descriptor) generates (Error error); /* Loading @@ -124,6 +134,7 @@ interface IAllocator { * UNSUPPORTED when any of the descriptors can never be satisfied. * UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities. */ @callflow(next="allocate") testAllocate(vec<BufferDescriptor> descriptors) generates (Error error); /* Loading @@ -147,6 +158,7 @@ interface IAllocator { * time. * @return buffers is the allocated buffers. */ @callflow(next="exportHandle") allocate(vec<BufferDescriptor> descriptors) generates (Error error, vec<Buffer> buffers); Loading @@ -158,6 +170,8 @@ interface IAllocator { * @return error is NONE upon success. Otherwise, * BAD_BUFFER when the buffer is invalid. */ @exit @callflow(next="*") free(Buffer buffer) generates (Error error); /* Loading @@ -182,6 +196,7 @@ interface IAllocator { * NO_RESOURCES when the buffer cannot be exported at this time. * @return bufferHandle is the exported handle. */ @callflow(next="free") exportHandle(BufferDescriptor descriptor, Buffer buffer) generates (Error error, Loading graphics/allocator/2.0/vts/Allocator.vts 0 → 100644 +215 −0 Original line number Diff line number Diff line component_class: HAL_HIDL component_type_version: 2.0 component_name: "IAllocator" package: "android.hardware.graphics.allocator" import: "android.hardware.graphics.allocator@2.0::types" interface: { attribute: { name: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability" type: TYPE_ENUM enum_value: { scalar_type: "int32_t" enumerator: "INVALID" scalar_value: { int32_t: 0 } enumerator: "TEST_ALLOCATE" scalar_value: { int32_t: 1 } } } attribute: { name: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo" type: TYPE_STRUCT struct_value: { name: "width" type: TYPE_SCALAR scalar_type: "uint32_t" } struct_value: { name: "height" type: TYPE_SCALAR scalar_type: "uint32_t" } struct_value: { name: "format" type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::PixelFormat" } struct_value: { name: "producerUsageMask" type: TYPE_SCALAR scalar_type: "uint64_t" } struct_value: { name: "consumerUsageMask" type: TYPE_SCALAR scalar_type: "uint64_t" } } api: { name: "getCapabilities" return_type_hidl: { type: TYPE_VECTOR vector_value: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability" } } callflow: { entry: true } callflow: { exit: true } callflow: { next: "*" } } api: { name: "dumpDebugInfo" return_type_hidl: { type: TYPE_STRING } callflow: { entry: true } callflow: { exit: true } callflow: { next: "*" } } api: { name: "createDescriptor" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { type: TYPE_SCALAR scalar_type: "uint64_t" } arg: { type: TYPE_STRUCT predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo" } callflow: { entry: true } callflow: { next: "*" } } api: { name: "destroyDescriptor" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { exit: true } callflow: { next: "*" } } api: { name: "testAllocate" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } callflow: { next: "allocate" } } api: { name: "allocate" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } arg: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } callflow: { next: "exportHandle" } } api: { name: "free" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { exit: true } callflow: { next: "*" } } api: { name: "exportHandle" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { next: "free" } } } graphics/allocator/2.0/vts/functional/Android.bp 0 → 100644 +37 −0 Original line number Diff line number Diff line // // Copyright (C) 2016 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // cc_test { name: "graphics_allocator_hidl_hal_test", gtest: true, srcs: ["graphics_allocator_hidl_hal_test.cpp"], shared_libs: [ "libbase", "liblog", "libcutils", "libhidlbase", "libhidltransport", "libhwbinder", "libnativehelper", "libutils", "android.hardware.graphics.allocator@2.0", ], static_libs: ["libgtest"], cflags: [ "-O0", "-g", ], } graphics/allocator/2.0/vts/functional/graphics_allocator_hidl_hal_test.cpp 0 → 100644 +304 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "graphics_allocator_hidl_hal_test" #include <unordered_set> #include <android-base/logging.h> #include <android/hardware/graphics/allocator/2.0/IAllocator.h> #include <gtest/gtest.h> namespace android { namespace hardware { namespace graphics { namespace allocator { namespace V2_0 { namespace tests { namespace { using android::hardware::graphics::common::V1_0::PixelFormat; #define CHECK_FEATURE_OR_SKIP(FEATURE_NAME) \ do { \ if (!hasCapability(FEATURE_NAME)) { \ std::cout << "[ SKIPPED ] Feature " << #FEATURE_NAME \ << " not supported" << std::endl; \ return; \ } \ } while (0) class TempDescriptor { public: TempDescriptor(const sp<IAllocator>& allocator, const IAllocator::BufferDescriptorInfo& info) : mAllocator(allocator), mError(Error::NO_RESOURCES) { mAllocator->createDescriptor( info, [&](const auto& tmpError, const auto& tmpDescriptor) { mError = tmpError; mDescriptor = tmpDescriptor; }); } ~TempDescriptor() { if (mError == Error::NONE) { mAllocator->destroyDescriptor(mDescriptor); } } bool isValid() const { return (mError == Error::NONE); } operator BufferDescriptor() const { return mDescriptor; } private: sp<IAllocator> mAllocator; Error mError; BufferDescriptor mDescriptor; }; class GraphicsAllocatorHidlTest : public ::testing::Test { protected: void SetUp() override { mAllocator = IAllocator::getService("gralloc"); ASSERT_NE(mAllocator, nullptr); initCapabilities(); mDummyDescriptorInfo.width = 64; mDummyDescriptorInfo.height = 64; mDummyDescriptorInfo.format = PixelFormat::RGBA_8888; mDummyDescriptorInfo.producerUsageMask = static_cast<uint64_t>(ProducerUsage::CPU_WRITE); mDummyDescriptorInfo.consumerUsageMask = static_cast<uint64_t>(ConsumerUsage::CPU_READ); } void TearDown() override {} /** * Initialize the set of supported capabilities. */ void initCapabilities() { mAllocator->getCapabilities([this](const auto& capabilities) { std::vector<IAllocator::Capability> caps = capabilities; mCapabilities.insert(caps.cbegin(), caps.cend()); }); } /** * Test whether a capability is supported. */ bool hasCapability(IAllocator::Capability capability) const { return (mCapabilities.count(capability) > 0); } sp<IAllocator> mAllocator; IAllocator::BufferDescriptorInfo mDummyDescriptorInfo{}; private: std::unordered_set<IAllocator::Capability> mCapabilities; }; TEST_F(GraphicsAllocatorHidlTest, GetCapabilities) { auto ret = mAllocator->getCapabilities([](const auto& capabilities) { std::vector<IAllocator::Capability> caps = capabilities; for (auto cap : caps) { EXPECT_NE(IAllocator::Capability::INVALID, cap); } }); ASSERT_TRUE(ret.getStatus().isOk()); } TEST_F(GraphicsAllocatorHidlTest, DumpDebugInfo) { auto ret = mAllocator->dumpDebugInfo([](const auto&) { // nothing to do }); ASSERT_TRUE(ret.getStatus().isOk()); } TEST_F(GraphicsAllocatorHidlTest, CreateDestroyDescriptor) { Error error; BufferDescriptor descriptor; auto ret = mAllocator->createDescriptor( mDummyDescriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { error = tmpError; descriptor = tmpDescriptor; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_EQ(Error::NONE, error); auto err_ret = mAllocator->destroyDescriptor(descriptor); ASSERT_TRUE(err_ret.getStatus().isOk()); ASSERT_EQ(Error::NONE, static_cast<Error>(err_ret)); } /** * Test testAllocate with a single buffer descriptor. */ TEST_F(GraphicsAllocatorHidlTest, TestAllocateBasic) { CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE); TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; auto ret = mAllocator->testAllocate(descriptors); ASSERT_TRUE(ret.getStatus().isOk()); auto error = static_cast<Error>(ret); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); } /** * Test testAllocate with two buffer descriptors. */ TEST_F(GraphicsAllocatorHidlTest, TestAllocateArray) { CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE); TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(2); descriptors[0] = descriptor; descriptors[1] = descriptor; auto ret = mAllocator->testAllocate(descriptors); ASSERT_TRUE(ret.getStatus().isOk()); auto error = static_cast<Error>(ret); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); } /** * Test allocate/free with a single buffer descriptor. */ TEST_F(GraphicsAllocatorHidlTest, AllocateFreeBasic) { TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); EXPECT_EQ(1u, buffers.size()); if (!buffers.empty()) { auto err_ret = mAllocator->free(buffers[0]); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } /** * Test allocate/free with an array of buffer descriptors. */ TEST_F(GraphicsAllocatorHidlTest, AllocateFreeArray) { TempDescriptor descriptor1(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor1.isValid()); TempDescriptor descriptor2(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor2.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(3); descriptors[0] = descriptor1; descriptors[1] = descriptor1; descriptors[2] = descriptor2; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); EXPECT_EQ(descriptors.size(), buffers.size()); for (auto buf : buffers) { auto err_ret = mAllocator->free(buf); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } TEST_F(GraphicsAllocatorHidlTest, ExportHandle) { TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); ASSERT_EQ(1u, buffers.size()); ret = mAllocator->exportHandle( descriptors[0], buffers[0], [&](const auto& tmpError, const auto&) { error = tmpError; }); EXPECT_TRUE(ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, error); auto err_ret = mAllocator->free(buffers[0]); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } // namespace anonymous } // namespace tests } // namespace V2_0 } // namespace allocator } // namespace graphics } // namespace hardware } // namespace android int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); ALOGI("Test result = %d", status); return status; } Loading
graphics/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ subdirs = [ "allocator/2.0", "allocator/2.0/default", "allocator/2.0/vts/functional", "common/1.0", "composer/2.1", "composer/2.1/default", Loading
graphics/allocator/2.0/IAllocator.hal +15 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,9 @@ interface IAllocator { * * @return capabilities is a list of supported capabilities. */ @entry @exit @callflow(next="*") getCapabilities() generates (vec<Capability> capabilities); /* Loading @@ -86,6 +89,9 @@ interface IAllocator { * * @return debugInfo is a string of debug information. */ @entry @exit @callflow(next="*") dumpDebugInfo() generates (string debugInfo); /* Loading @@ -98,6 +104,8 @@ interface IAllocator { * NO_RESOURCES when no more descriptors can currently be created. * @return descriptor is the newly created buffer descriptor. */ @entry @callflow(next="*") createDescriptor(BufferDescriptorInfo descriptorInfo) generates (Error error, BufferDescriptor descriptor); Loading @@ -108,6 +116,8 @@ interface IAllocator { * @param descriptor is the descriptor to destroy. * @return error is either NONE or BAD_DESCRIPTOR. */ @exit @callflow(next="*") destroyDescriptor(BufferDescriptor descriptor) generates (Error error); /* Loading @@ -124,6 +134,7 @@ interface IAllocator { * UNSUPPORTED when any of the descriptors can never be satisfied. * UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities. */ @callflow(next="allocate") testAllocate(vec<BufferDescriptor> descriptors) generates (Error error); /* Loading @@ -147,6 +158,7 @@ interface IAllocator { * time. * @return buffers is the allocated buffers. */ @callflow(next="exportHandle") allocate(vec<BufferDescriptor> descriptors) generates (Error error, vec<Buffer> buffers); Loading @@ -158,6 +170,8 @@ interface IAllocator { * @return error is NONE upon success. Otherwise, * BAD_BUFFER when the buffer is invalid. */ @exit @callflow(next="*") free(Buffer buffer) generates (Error error); /* Loading @@ -182,6 +196,7 @@ interface IAllocator { * NO_RESOURCES when the buffer cannot be exported at this time. * @return bufferHandle is the exported handle. */ @callflow(next="free") exportHandle(BufferDescriptor descriptor, Buffer buffer) generates (Error error, Loading
graphics/allocator/2.0/vts/Allocator.vts 0 → 100644 +215 −0 Original line number Diff line number Diff line component_class: HAL_HIDL component_type_version: 2.0 component_name: "IAllocator" package: "android.hardware.graphics.allocator" import: "android.hardware.graphics.allocator@2.0::types" interface: { attribute: { name: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability" type: TYPE_ENUM enum_value: { scalar_type: "int32_t" enumerator: "INVALID" scalar_value: { int32_t: 0 } enumerator: "TEST_ALLOCATE" scalar_value: { int32_t: 1 } } } attribute: { name: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo" type: TYPE_STRUCT struct_value: { name: "width" type: TYPE_SCALAR scalar_type: "uint32_t" } struct_value: { name: "height" type: TYPE_SCALAR scalar_type: "uint32_t" } struct_value: { name: "format" type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::PixelFormat" } struct_value: { name: "producerUsageMask" type: TYPE_SCALAR scalar_type: "uint64_t" } struct_value: { name: "consumerUsageMask" type: TYPE_SCALAR scalar_type: "uint64_t" } } api: { name: "getCapabilities" return_type_hidl: { type: TYPE_VECTOR vector_value: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability" } } callflow: { entry: true } callflow: { exit: true } callflow: { next: "*" } } api: { name: "dumpDebugInfo" return_type_hidl: { type: TYPE_STRING } callflow: { entry: true } callflow: { exit: true } callflow: { next: "*" } } api: { name: "createDescriptor" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { type: TYPE_SCALAR scalar_type: "uint64_t" } arg: { type: TYPE_STRUCT predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo" } callflow: { entry: true } callflow: { next: "*" } } api: { name: "destroyDescriptor" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { exit: true } callflow: { next: "*" } } api: { name: "testAllocate" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } callflow: { next: "allocate" } } api: { name: "allocate" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } arg: { type: TYPE_VECTOR vector_value: { type: TYPE_SCALAR scalar_type: "uint64_t" } } callflow: { next: "exportHandle" } } api: { name: "free" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { exit: true } callflow: { next: "*" } } api: { name: "exportHandle" return_type_hidl: { type: TYPE_ENUM predefined_type: "::android::hardware::graphics::allocator::V2_0::Error" } return_type_hidl: { } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } arg: { type: TYPE_SCALAR scalar_type: "uint64_t" } callflow: { next: "free" } } }
graphics/allocator/2.0/vts/functional/Android.bp 0 → 100644 +37 −0 Original line number Diff line number Diff line // // Copyright (C) 2016 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // cc_test { name: "graphics_allocator_hidl_hal_test", gtest: true, srcs: ["graphics_allocator_hidl_hal_test.cpp"], shared_libs: [ "libbase", "liblog", "libcutils", "libhidlbase", "libhidltransport", "libhwbinder", "libnativehelper", "libutils", "android.hardware.graphics.allocator@2.0", ], static_libs: ["libgtest"], cflags: [ "-O0", "-g", ], }
graphics/allocator/2.0/vts/functional/graphics_allocator_hidl_hal_test.cpp 0 → 100644 +304 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "graphics_allocator_hidl_hal_test" #include <unordered_set> #include <android-base/logging.h> #include <android/hardware/graphics/allocator/2.0/IAllocator.h> #include <gtest/gtest.h> namespace android { namespace hardware { namespace graphics { namespace allocator { namespace V2_0 { namespace tests { namespace { using android::hardware::graphics::common::V1_0::PixelFormat; #define CHECK_FEATURE_OR_SKIP(FEATURE_NAME) \ do { \ if (!hasCapability(FEATURE_NAME)) { \ std::cout << "[ SKIPPED ] Feature " << #FEATURE_NAME \ << " not supported" << std::endl; \ return; \ } \ } while (0) class TempDescriptor { public: TempDescriptor(const sp<IAllocator>& allocator, const IAllocator::BufferDescriptorInfo& info) : mAllocator(allocator), mError(Error::NO_RESOURCES) { mAllocator->createDescriptor( info, [&](const auto& tmpError, const auto& tmpDescriptor) { mError = tmpError; mDescriptor = tmpDescriptor; }); } ~TempDescriptor() { if (mError == Error::NONE) { mAllocator->destroyDescriptor(mDescriptor); } } bool isValid() const { return (mError == Error::NONE); } operator BufferDescriptor() const { return mDescriptor; } private: sp<IAllocator> mAllocator; Error mError; BufferDescriptor mDescriptor; }; class GraphicsAllocatorHidlTest : public ::testing::Test { protected: void SetUp() override { mAllocator = IAllocator::getService("gralloc"); ASSERT_NE(mAllocator, nullptr); initCapabilities(); mDummyDescriptorInfo.width = 64; mDummyDescriptorInfo.height = 64; mDummyDescriptorInfo.format = PixelFormat::RGBA_8888; mDummyDescriptorInfo.producerUsageMask = static_cast<uint64_t>(ProducerUsage::CPU_WRITE); mDummyDescriptorInfo.consumerUsageMask = static_cast<uint64_t>(ConsumerUsage::CPU_READ); } void TearDown() override {} /** * Initialize the set of supported capabilities. */ void initCapabilities() { mAllocator->getCapabilities([this](const auto& capabilities) { std::vector<IAllocator::Capability> caps = capabilities; mCapabilities.insert(caps.cbegin(), caps.cend()); }); } /** * Test whether a capability is supported. */ bool hasCapability(IAllocator::Capability capability) const { return (mCapabilities.count(capability) > 0); } sp<IAllocator> mAllocator; IAllocator::BufferDescriptorInfo mDummyDescriptorInfo{}; private: std::unordered_set<IAllocator::Capability> mCapabilities; }; TEST_F(GraphicsAllocatorHidlTest, GetCapabilities) { auto ret = mAllocator->getCapabilities([](const auto& capabilities) { std::vector<IAllocator::Capability> caps = capabilities; for (auto cap : caps) { EXPECT_NE(IAllocator::Capability::INVALID, cap); } }); ASSERT_TRUE(ret.getStatus().isOk()); } TEST_F(GraphicsAllocatorHidlTest, DumpDebugInfo) { auto ret = mAllocator->dumpDebugInfo([](const auto&) { // nothing to do }); ASSERT_TRUE(ret.getStatus().isOk()); } TEST_F(GraphicsAllocatorHidlTest, CreateDestroyDescriptor) { Error error; BufferDescriptor descriptor; auto ret = mAllocator->createDescriptor( mDummyDescriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { error = tmpError; descriptor = tmpDescriptor; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_EQ(Error::NONE, error); auto err_ret = mAllocator->destroyDescriptor(descriptor); ASSERT_TRUE(err_ret.getStatus().isOk()); ASSERT_EQ(Error::NONE, static_cast<Error>(err_ret)); } /** * Test testAllocate with a single buffer descriptor. */ TEST_F(GraphicsAllocatorHidlTest, TestAllocateBasic) { CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE); TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; auto ret = mAllocator->testAllocate(descriptors); ASSERT_TRUE(ret.getStatus().isOk()); auto error = static_cast<Error>(ret); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); } /** * Test testAllocate with two buffer descriptors. */ TEST_F(GraphicsAllocatorHidlTest, TestAllocateArray) { CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE); TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(2); descriptors[0] = descriptor; descriptors[1] = descriptor; auto ret = mAllocator->testAllocate(descriptors); ASSERT_TRUE(ret.getStatus().isOk()); auto error = static_cast<Error>(ret); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); } /** * Test allocate/free with a single buffer descriptor. */ TEST_F(GraphicsAllocatorHidlTest, AllocateFreeBasic) { TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); EXPECT_EQ(1u, buffers.size()); if (!buffers.empty()) { auto err_ret = mAllocator->free(buffers[0]); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } /** * Test allocate/free with an array of buffer descriptors. */ TEST_F(GraphicsAllocatorHidlTest, AllocateFreeArray) { TempDescriptor descriptor1(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor1.isValid()); TempDescriptor descriptor2(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor2.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(3); descriptors[0] = descriptor1; descriptors[1] = descriptor1; descriptors[2] = descriptor2; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); EXPECT_EQ(descriptors.size(), buffers.size()); for (auto buf : buffers) { auto err_ret = mAllocator->free(buf); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } TEST_F(GraphicsAllocatorHidlTest, ExportHandle) { TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo); ASSERT_TRUE(descriptor.isValid()); hidl_vec<BufferDescriptor> descriptors; descriptors.resize(1); descriptors[0] = descriptor; Error error; std::vector<Buffer> buffers; auto ret = mAllocator->allocate( descriptors, [&](const auto& tmpError, const auto& tmpBuffers) { error = tmpError; buffers = tmpBuffers; }); ASSERT_TRUE(ret.getStatus().isOk()); ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED); ASSERT_EQ(1u, buffers.size()); ret = mAllocator->exportHandle( descriptors[0], buffers[0], [&](const auto& tmpError, const auto&) { error = tmpError; }); EXPECT_TRUE(ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, error); auto err_ret = mAllocator->free(buffers[0]); EXPECT_TRUE(err_ret.getStatus().isOk()); EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret)); } } // namespace anonymous } // namespace tests } // namespace V2_0 } // namespace allocator } // namespace graphics } // namespace hardware } // namespace android int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); ALOGI("Test result = %d", status); return status; }