Loading media/libstagefright/codec2/vndk/bufferpool/Android.bp +2 −2 Original line number Diff line number Diff line cc_library_shared { name: "android.hardware.media.bufferpool@1.0-impl", cc_library { name: "libstagefright_bufferpool@1.0", vendor_available: true, vndk: { enabled: true, Loading media/libstagefright/codec2/vndk/bufferpool/vts/Android.bp 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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_test { name: "VtsVndkHidlBufferpoolV1_0TargetSingleTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ "single.cpp", ], static_libs: [ "android.hardware.media.bufferpool@1.0", "libion", "libstagefright_bufferpool@1.0", ], shared_libs: [ "libfmq", "libstagefright_codec2", "libstagefright_codec2_vndk", ], compile_multilib: "both", } cc_test { name: "VtsVndkHidlBufferpoolV1_0TargetMultiTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ "multi.cpp", ], static_libs: [ "android.hardware.media.bufferpool@1.0", "libion", "libstagefright_bufferpool@1.0", ], shared_libs: [ "libfmq", "libstagefright_codec2", "libstagefright_codec2_vndk", ], compile_multilib: "both", } media/libstagefright/codec2/vndk/bufferpool/vts/OWNERS 0 → 100644 +7 −0 Original line number Diff line number Diff line # Media team taklee@google.com lajos@google.com # VTS team yim@google.com zhuoyao@google.com media/libstagefright/codec2/vndk/bufferpool/vts/multi.cpp 0 → 100644 +240 −0 Original line number Diff line number Diff line /* * 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 "buffferpool_unit_test" #include <gtest/gtest.h> #include <C2AllocatorIon.h> #include <C2Buffer.h> #include <C2PlatformSupport.h> #include <ClientManager.h> #include <android-base/logging.h> #include <binder/ProcessState.h> #include <hidl/HidlSupport.h> #include <hidl/HidlTransportSupport.h> #include <hidl/LegacySupport.h> #include <hidl/Status.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <iostream> #include <memory> #include <vector> using android::C2AllocatorIon; using android::C2PlatformAllocatorStore; using android::hardware::configureRpcThreadpool; using android::hardware::hidl_handle; using android::hardware::media::bufferpool::V1_0::IAccessor; using android::hardware::media::bufferpool::V1_0::IClientManager; using android::hardware::media::bufferpool::V1_0::ResultStatus; using android::hardware::media::bufferpool::V1_0::implementation::BufferId; using android::hardware::media::bufferpool::V1_0::implementation::ClientManager; using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId; using android::hardware::media::bufferpool::V1_0::implementation::TransactionId; namespace { // Buffer allocation size for tests. constexpr static int kAllocationSize = 1024 * 10; // communication message types between processes. enum PipeCommand : int32_t { INIT_OK = 0, INIT_ERROR, SEND, RECEIVE_OK, RECEIVE_ERROR, }; // communication message between processes. union PipeMessage { struct { int32_t command; BufferId bufferId; ConnectionId connectionId; TransactionId transactionId; int64_t timestampUs; } data; char array[0]; }; // media.bufferpool test setup class BufferpoolMultiTest : public ::testing::Test { public: virtual void SetUp() override { ResultStatus status; mReceiverPid = -1; ASSERT_TRUE(pipe(mCommandPipeFds) == 0); ASSERT_TRUE(pipe(mResultPipeFds) == 0); mReceiverPid = fork(); ASSERT_TRUE(mReceiverPid >= 0); if (mReceiverPid == 0) { doReceiver(); return; } mManager = ClientManager::getInstance(); ASSERT_NE(mManager, nullptr); mAllocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION); ASSERT_TRUE((bool)mAllocator); status = mManager->create(mAllocator, true, &mConnectionId); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->getAccessor(mConnectionId, &mAccessor); ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor); } virtual void TearDown() override { if (mReceiverPid > 0) { kill(mReceiverPid, SIGKILL); int wstatus; wait(&wstatus); } } protected: static void description(const std::string& description) { RecordProperty("description", description); } android::sp<ClientManager> mManager; android::sp<IAccessor> mAccessor; std::shared_ptr<C2Allocator> mAllocator; ConnectionId mConnectionId; pid_t mReceiverPid; int mCommandPipeFds[2]; int mResultPipeFds[2]; void getAllocationParams(std::vector<uint8_t>* vecParams) { union Params { struct { uint32_t capacity; C2MemoryUsage usage; } data; uint8_t array[0]; Params() : data{kAllocationSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}} {} } params; vecParams->assign(params.array, params.array + sizeof(params)); } bool sendMessage(int *pipes, const PipeMessage &message) { int ret = write(pipes[1], message.array, sizeof(PipeMessage)); return ret == sizeof(PipeMessage); } bool receiveMessage(int *pipes, PipeMessage *message) { int ret = read(pipes[0], message->array, sizeof(PipeMessage)); return ret == sizeof(PipeMessage); } void doReceiver() { configureRpcThreadpool(1, false); PipeMessage message; mManager = ClientManager::getInstance(); if (!mManager) { message.data.command = PipeCommand::INIT_ERROR; sendMessage(mResultPipeFds, message); return; } android::status_t status = mManager->registerAsService(); if (status != android::OK) { message.data.command = PipeCommand::INIT_ERROR; sendMessage(mResultPipeFds, message); return; } message.data.command = PipeCommand::INIT_OK; sendMessage(mResultPipeFds, message); receiveMessage(mCommandPipeFds, &message); { std::shared_ptr<_C2BlockPoolData> rbuffer; ResultStatus status = mManager->receive( message.data.connectionId, message.data.transactionId, message.data.bufferId, message.data.timestampUs, &rbuffer); if (status != ResultStatus::OK) { message.data.command = PipeCommand::RECEIVE_ERROR; sendMessage(mResultPipeFds, message); return; } } message.data.command = PipeCommand::RECEIVE_OK; sendMessage(mResultPipeFds, message); while(1); // An easy way to ignore gtest behaviour. } }; // Buffer transfer test between processes. TEST_F(BufferpoolMultiTest, TransferBuffer) { ResultStatus status; PipeMessage message; ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)); android::sp<IClientManager> receiver = IClientManager::getService(); ConnectionId receiverId; ASSERT_TRUE((bool)receiver); receiver->registerSender( mAccessor, [&status, &receiverId] (ResultStatus outStatus, ConnectionId outId) { status = outStatus; receiverId = outId; }); ASSERT_TRUE(status == ResultStatus::OK); { std::shared_ptr<_C2BlockPoolData> sbuffer; TransactionId transactionId; int64_t postUs; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); status = mManager->allocate(mConnectionId, vecParams, &sbuffer); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->postSend(mConnectionId, receiverId, sbuffer, &transactionId, &postUs); ASSERT_TRUE(status == ResultStatus::OK); message.data.command = PipeCommand::SEND; message.data.bufferId = sbuffer->mId; message.data.connectionId = receiverId; message.data.transactionId = transactionId; message.data.timestampUs = postUs; sendMessage(mCommandPipeFds, message); } EXPECT_TRUE(receiveMessage(mResultPipeFds, &message)); } } // anonymous namespace int main(int argc, char** argv) { setenv("TREBLE_TESTING_OVERRIDE", "true", true); ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); LOG(INFO) << "Test result = " << status; return status; } media/libstagefright/codec2/vndk/bufferpool/vts/single.cpp 0 → 100644 +182 −0 Original line number Diff line number Diff line /* * 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 "buffferpool_unit_test" #include <gtest/gtest.h> #include <C2AllocatorIon.h> #include <C2Buffer.h> #include <C2PlatformSupport.h> #include <ClientManager.h> #include <android-base/logging.h> #include <binder/ProcessState.h> #include <hidl/HidlSupport.h> #include <hidl/HidlTransportSupport.h> #include <hidl/LegacySupport.h> #include <hidl/Status.h> #include <unistd.h> #include <iostream> #include <memory> #include <vector> using android::C2AllocatorIon; using android::C2PlatformAllocatorStore; using android::hardware::hidl_handle; using android::hardware::media::bufferpool::V1_0::IAccessor; using android::hardware::media::bufferpool::V1_0::ResultStatus; using android::hardware::media::bufferpool::V1_0::implementation::BufferId; using android::hardware::media::bufferpool::V1_0::implementation::ClientManager; using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId; using android::hardware::media::bufferpool::V1_0::implementation::TransactionId; namespace { // Buffer allocation size for tests. constexpr static int kAllocationSize = 1024 * 10; // Number of iteration for buffer allocation test. constexpr static int kNumAllocationTest = 3; // Number of iteration for buffer recycling test. constexpr static int kNumRecycleTest = 3; // media.bufferpool test setup class BufferpoolSingleTest : public ::testing::Test { public: virtual void SetUp() override { ResultStatus status; mManager = ClientManager::getInstance(); ASSERT_NE(mManager, nullptr); mAllocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION); ASSERT_TRUE((bool)mAllocator); status = mManager->create(mAllocator, true, &mConnectionId); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->getAccessor(mConnectionId, &mAccessor); ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor); ConnectionId& receiverId = mReceiverId; mManager->registerSender( mAccessor, [&status, &receiverId](ResultStatus hidlStatus, ConnectionId hidlId) { status = hidlStatus; receiverId = hidlId; }); ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS && receiverId == mConnectionId); } protected: static void description(const std::string& description) { RecordProperty("description", description); } android::sp<ClientManager> mManager; android::sp<IAccessor> mAccessor; std::shared_ptr<C2Allocator> mAllocator; ConnectionId mConnectionId; ConnectionId mReceiverId; void getAllocationParams(std::vector<uint8_t>* vecParams) { union Params { struct { uint32_t capacity; C2MemoryUsage usage; } data; uint8_t array[0]; Params() : data{kAllocationSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}} {} } params; vecParams->assign(params.array, params.array + sizeof(params)); } }; // Buffer allocation test. // Check whether each buffer allocation is done successfully with // unique buffer id. TEST_F(BufferpoolSingleTest, AllocateBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); std::shared_ptr<_C2BlockPoolData> buffer[kNumAllocationTest]; for (int i = 0; i < kNumAllocationTest; ++i) { status = mManager->allocate(mConnectionId, vecParams, &buffer[i]); ASSERT_TRUE(status == ResultStatus::OK); } for (int i = 0; i < kNumAllocationTest; ++i) { for (int j = i + 1; j < kNumAllocationTest; ++j) { ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId); } } EXPECT_TRUE(kNumAllocationTest > 1); } // Buffer recycle test. // Check whether de-allocated buffers are recycled. TEST_F(BufferpoolSingleTest, RecycleBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); BufferId bid[kNumRecycleTest]; for (int i = 0; i < kNumRecycleTest; ++i) { std::shared_ptr<_C2BlockPoolData> buffer; status = mManager->allocate(mConnectionId, vecParams, &buffer); ASSERT_TRUE(status == ResultStatus::OK); bid[i] = buffer->mId; } for (int i = 1; i < kNumRecycleTest; ++i) { ASSERT_TRUE(bid[i - 1] == bid[i]); } EXPECT_TRUE(kNumRecycleTest > 1); } // Buffer transfer test. // Check whether buffer is transferred to another client successfully. TEST_F(BufferpoolSingleTest, TransferBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); std::shared_ptr<_C2BlockPoolData> sbuffer, rbuffer; TransactionId transactionId; int64_t postUs; status = mManager->allocate(mConnectionId, vecParams, &sbuffer); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->postSend(mConnectionId, mReceiverId, sbuffer, &transactionId, &postUs); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs, &rbuffer); EXPECT_TRUE(status == ResultStatus::OK); } } // anonymous namespace int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); LOG(INFO) << "Test result = " << status; return status; } Loading
media/libstagefright/codec2/vndk/bufferpool/Android.bp +2 −2 Original line number Diff line number Diff line cc_library_shared { name: "android.hardware.media.bufferpool@1.0-impl", cc_library { name: "libstagefright_bufferpool@1.0", vendor_available: true, vndk: { enabled: true, Loading
media/libstagefright/codec2/vndk/bufferpool/vts/Android.bp 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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_test { name: "VtsVndkHidlBufferpoolV1_0TargetSingleTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ "single.cpp", ], static_libs: [ "android.hardware.media.bufferpool@1.0", "libion", "libstagefright_bufferpool@1.0", ], shared_libs: [ "libfmq", "libstagefright_codec2", "libstagefright_codec2_vndk", ], compile_multilib: "both", } cc_test { name: "VtsVndkHidlBufferpoolV1_0TargetMultiTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ "multi.cpp", ], static_libs: [ "android.hardware.media.bufferpool@1.0", "libion", "libstagefright_bufferpool@1.0", ], shared_libs: [ "libfmq", "libstagefright_codec2", "libstagefright_codec2_vndk", ], compile_multilib: "both", }
media/libstagefright/codec2/vndk/bufferpool/vts/OWNERS 0 → 100644 +7 −0 Original line number Diff line number Diff line # Media team taklee@google.com lajos@google.com # VTS team yim@google.com zhuoyao@google.com
media/libstagefright/codec2/vndk/bufferpool/vts/multi.cpp 0 → 100644 +240 −0 Original line number Diff line number Diff line /* * 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 "buffferpool_unit_test" #include <gtest/gtest.h> #include <C2AllocatorIon.h> #include <C2Buffer.h> #include <C2PlatformSupport.h> #include <ClientManager.h> #include <android-base/logging.h> #include <binder/ProcessState.h> #include <hidl/HidlSupport.h> #include <hidl/HidlTransportSupport.h> #include <hidl/LegacySupport.h> #include <hidl/Status.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <iostream> #include <memory> #include <vector> using android::C2AllocatorIon; using android::C2PlatformAllocatorStore; using android::hardware::configureRpcThreadpool; using android::hardware::hidl_handle; using android::hardware::media::bufferpool::V1_0::IAccessor; using android::hardware::media::bufferpool::V1_0::IClientManager; using android::hardware::media::bufferpool::V1_0::ResultStatus; using android::hardware::media::bufferpool::V1_0::implementation::BufferId; using android::hardware::media::bufferpool::V1_0::implementation::ClientManager; using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId; using android::hardware::media::bufferpool::V1_0::implementation::TransactionId; namespace { // Buffer allocation size for tests. constexpr static int kAllocationSize = 1024 * 10; // communication message types between processes. enum PipeCommand : int32_t { INIT_OK = 0, INIT_ERROR, SEND, RECEIVE_OK, RECEIVE_ERROR, }; // communication message between processes. union PipeMessage { struct { int32_t command; BufferId bufferId; ConnectionId connectionId; TransactionId transactionId; int64_t timestampUs; } data; char array[0]; }; // media.bufferpool test setup class BufferpoolMultiTest : public ::testing::Test { public: virtual void SetUp() override { ResultStatus status; mReceiverPid = -1; ASSERT_TRUE(pipe(mCommandPipeFds) == 0); ASSERT_TRUE(pipe(mResultPipeFds) == 0); mReceiverPid = fork(); ASSERT_TRUE(mReceiverPid >= 0); if (mReceiverPid == 0) { doReceiver(); return; } mManager = ClientManager::getInstance(); ASSERT_NE(mManager, nullptr); mAllocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION); ASSERT_TRUE((bool)mAllocator); status = mManager->create(mAllocator, true, &mConnectionId); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->getAccessor(mConnectionId, &mAccessor); ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor); } virtual void TearDown() override { if (mReceiverPid > 0) { kill(mReceiverPid, SIGKILL); int wstatus; wait(&wstatus); } } protected: static void description(const std::string& description) { RecordProperty("description", description); } android::sp<ClientManager> mManager; android::sp<IAccessor> mAccessor; std::shared_ptr<C2Allocator> mAllocator; ConnectionId mConnectionId; pid_t mReceiverPid; int mCommandPipeFds[2]; int mResultPipeFds[2]; void getAllocationParams(std::vector<uint8_t>* vecParams) { union Params { struct { uint32_t capacity; C2MemoryUsage usage; } data; uint8_t array[0]; Params() : data{kAllocationSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}} {} } params; vecParams->assign(params.array, params.array + sizeof(params)); } bool sendMessage(int *pipes, const PipeMessage &message) { int ret = write(pipes[1], message.array, sizeof(PipeMessage)); return ret == sizeof(PipeMessage); } bool receiveMessage(int *pipes, PipeMessage *message) { int ret = read(pipes[0], message->array, sizeof(PipeMessage)); return ret == sizeof(PipeMessage); } void doReceiver() { configureRpcThreadpool(1, false); PipeMessage message; mManager = ClientManager::getInstance(); if (!mManager) { message.data.command = PipeCommand::INIT_ERROR; sendMessage(mResultPipeFds, message); return; } android::status_t status = mManager->registerAsService(); if (status != android::OK) { message.data.command = PipeCommand::INIT_ERROR; sendMessage(mResultPipeFds, message); return; } message.data.command = PipeCommand::INIT_OK; sendMessage(mResultPipeFds, message); receiveMessage(mCommandPipeFds, &message); { std::shared_ptr<_C2BlockPoolData> rbuffer; ResultStatus status = mManager->receive( message.data.connectionId, message.data.transactionId, message.data.bufferId, message.data.timestampUs, &rbuffer); if (status != ResultStatus::OK) { message.data.command = PipeCommand::RECEIVE_ERROR; sendMessage(mResultPipeFds, message); return; } } message.data.command = PipeCommand::RECEIVE_OK; sendMessage(mResultPipeFds, message); while(1); // An easy way to ignore gtest behaviour. } }; // Buffer transfer test between processes. TEST_F(BufferpoolMultiTest, TransferBuffer) { ResultStatus status; PipeMessage message; ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)); android::sp<IClientManager> receiver = IClientManager::getService(); ConnectionId receiverId; ASSERT_TRUE((bool)receiver); receiver->registerSender( mAccessor, [&status, &receiverId] (ResultStatus outStatus, ConnectionId outId) { status = outStatus; receiverId = outId; }); ASSERT_TRUE(status == ResultStatus::OK); { std::shared_ptr<_C2BlockPoolData> sbuffer; TransactionId transactionId; int64_t postUs; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); status = mManager->allocate(mConnectionId, vecParams, &sbuffer); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->postSend(mConnectionId, receiverId, sbuffer, &transactionId, &postUs); ASSERT_TRUE(status == ResultStatus::OK); message.data.command = PipeCommand::SEND; message.data.bufferId = sbuffer->mId; message.data.connectionId = receiverId; message.data.transactionId = transactionId; message.data.timestampUs = postUs; sendMessage(mCommandPipeFds, message); } EXPECT_TRUE(receiveMessage(mResultPipeFds, &message)); } } // anonymous namespace int main(int argc, char** argv) { setenv("TREBLE_TESTING_OVERRIDE", "true", true); ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); LOG(INFO) << "Test result = " << status; return status; }
media/libstagefright/codec2/vndk/bufferpool/vts/single.cpp 0 → 100644 +182 −0 Original line number Diff line number Diff line /* * 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 "buffferpool_unit_test" #include <gtest/gtest.h> #include <C2AllocatorIon.h> #include <C2Buffer.h> #include <C2PlatformSupport.h> #include <ClientManager.h> #include <android-base/logging.h> #include <binder/ProcessState.h> #include <hidl/HidlSupport.h> #include <hidl/HidlTransportSupport.h> #include <hidl/LegacySupport.h> #include <hidl/Status.h> #include <unistd.h> #include <iostream> #include <memory> #include <vector> using android::C2AllocatorIon; using android::C2PlatformAllocatorStore; using android::hardware::hidl_handle; using android::hardware::media::bufferpool::V1_0::IAccessor; using android::hardware::media::bufferpool::V1_0::ResultStatus; using android::hardware::media::bufferpool::V1_0::implementation::BufferId; using android::hardware::media::bufferpool::V1_0::implementation::ClientManager; using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId; using android::hardware::media::bufferpool::V1_0::implementation::TransactionId; namespace { // Buffer allocation size for tests. constexpr static int kAllocationSize = 1024 * 10; // Number of iteration for buffer allocation test. constexpr static int kNumAllocationTest = 3; // Number of iteration for buffer recycling test. constexpr static int kNumRecycleTest = 3; // media.bufferpool test setup class BufferpoolSingleTest : public ::testing::Test { public: virtual void SetUp() override { ResultStatus status; mManager = ClientManager::getInstance(); ASSERT_NE(mManager, nullptr); mAllocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION); ASSERT_TRUE((bool)mAllocator); status = mManager->create(mAllocator, true, &mConnectionId); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->getAccessor(mConnectionId, &mAccessor); ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor); ConnectionId& receiverId = mReceiverId; mManager->registerSender( mAccessor, [&status, &receiverId](ResultStatus hidlStatus, ConnectionId hidlId) { status = hidlStatus; receiverId = hidlId; }); ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS && receiverId == mConnectionId); } protected: static void description(const std::string& description) { RecordProperty("description", description); } android::sp<ClientManager> mManager; android::sp<IAccessor> mAccessor; std::shared_ptr<C2Allocator> mAllocator; ConnectionId mConnectionId; ConnectionId mReceiverId; void getAllocationParams(std::vector<uint8_t>* vecParams) { union Params { struct { uint32_t capacity; C2MemoryUsage usage; } data; uint8_t array[0]; Params() : data{kAllocationSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}} {} } params; vecParams->assign(params.array, params.array + sizeof(params)); } }; // Buffer allocation test. // Check whether each buffer allocation is done successfully with // unique buffer id. TEST_F(BufferpoolSingleTest, AllocateBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); std::shared_ptr<_C2BlockPoolData> buffer[kNumAllocationTest]; for (int i = 0; i < kNumAllocationTest; ++i) { status = mManager->allocate(mConnectionId, vecParams, &buffer[i]); ASSERT_TRUE(status == ResultStatus::OK); } for (int i = 0; i < kNumAllocationTest; ++i) { for (int j = i + 1; j < kNumAllocationTest; ++j) { ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId); } } EXPECT_TRUE(kNumAllocationTest > 1); } // Buffer recycle test. // Check whether de-allocated buffers are recycled. TEST_F(BufferpoolSingleTest, RecycleBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); BufferId bid[kNumRecycleTest]; for (int i = 0; i < kNumRecycleTest; ++i) { std::shared_ptr<_C2BlockPoolData> buffer; status = mManager->allocate(mConnectionId, vecParams, &buffer); ASSERT_TRUE(status == ResultStatus::OK); bid[i] = buffer->mId; } for (int i = 1; i < kNumRecycleTest; ++i) { ASSERT_TRUE(bid[i - 1] == bid[i]); } EXPECT_TRUE(kNumRecycleTest > 1); } // Buffer transfer test. // Check whether buffer is transferred to another client successfully. TEST_F(BufferpoolSingleTest, TransferBuffer) { ResultStatus status; std::vector<uint8_t> vecParams; getAllocationParams(&vecParams); std::shared_ptr<_C2BlockPoolData> sbuffer, rbuffer; TransactionId transactionId; int64_t postUs; status = mManager->allocate(mConnectionId, vecParams, &sbuffer); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->postSend(mConnectionId, mReceiverId, sbuffer, &transactionId, &postUs); ASSERT_TRUE(status == ResultStatus::OK); status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs, &rbuffer); EXPECT_TRUE(status == ResultStatus::OK); } } // anonymous namespace int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); LOG(INFO) << "Test result = " << status; return status; }