Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db7d34ca authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I64d6c526,I3e8cfcdc am: 25f406f9 am: 253154a2 am: ed49938b

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1931642

Change-Id: I543b0a6411f15d2835d5f4a667e08c037244a853
parents 7a1d4829 ed49938b
Loading
Loading
Loading
Loading
+173 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ class BufferpoolTest {
  public:
    BufferpoolTest() : mConnectionValid(false), mManager(nullptr), mAllocator(nullptr) {
        mConnectionId = -1;
        mReceiverId = -1;
    }

    ~BufferpoolTest() {
@@ -83,6 +84,7 @@ class BufferpoolTest {
  protected:
    bool mConnectionValid;
    ConnectionId mConnectionId;
    ConnectionId mReceiverId;

    android::sp<ClientManager> mManager;
    std::shared_ptr<BufferPoolAllocator> mAllocator;
@@ -299,6 +301,89 @@ TEST_F(BufferpoolUnitTest, RecycleBuffer) {
    allocHandle.clear();
}

// Validate cache evict and invalidate APIs.
TEST_F(BufferpoolUnitTest, FlushTest) {
    std::vector<uint8_t> vecParams;
    getTestAllocatorParams(&vecParams);

    ResultStatus status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS && mReceiverId == mConnectionId);

    // testing empty flush
    status = mManager->flush(mConnectionId);
    ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;

    std::vector<std::shared_ptr<BufferPoolData>> senderBuffer{};
    std::vector<native_handle_t*> allocHandle{};
    std::vector<TransactionId> tid{};
    std::vector<int64_t> timestampUs{};

    std::map<TransactionId, BufferId> bufferMap{};

    for (int i = 0; i < kNumIterationCount; i++) {
        int64_t postUs;
        TransactionId transactionId;
        native_handle_t* handle = nullptr;
        std::shared_ptr<BufferPoolData> buffer{};
        status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
        ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << " iteration";

        ASSERT_TRUE(TestBufferPoolAllocator::Fill(handle, i));

        status = mManager->postSend(mReceiverId, buffer, &transactionId, &postUs);
        ASSERT_EQ(status, ResultStatus::OK) << "unable to post send transaction on bufferpool";

        timestampUs.push_back(postUs);
        tid.push_back(transactionId);
        bufferMap.insert({transactionId, buffer->mId});

        senderBuffer.push_back(std::move(buffer));
        if (handle) {
            allocHandle.push_back(std::move(handle));
        }
        buffer.reset();
    }

    status = mManager->flush(mConnectionId);
    ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;

    std::shared_ptr<BufferPoolData> receiverBuffer{};
    native_handle_t* recvHandle = nullptr;
    for (int i = 0; i < kNumIterationCount; i++) {
        status = mManager->receive(mReceiverId, tid[i], senderBuffer[i]->mId, timestampUs[i],
                                   &recvHandle, &receiverBuffer);
        ASSERT_EQ(status, ResultStatus::OK) << "receive failed for buffer " << senderBuffer[i]->mId;

        // find the buffer id from transaction id
        auto findIt = bufferMap.find(tid[i]);
        ASSERT_NE(findIt, bufferMap.end()) << "inconsistent buffer mapping";

        // buffer id received must be same as the buffer id sent
        ASSERT_EQ(findIt->second, receiverBuffer->mId) << "invalid buffer received";

        ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, i))
                << "Message received not same as that sent";

        bufferMap.erase(findIt);
        if (recvHandle) {
            native_handle_close(recvHandle);
            native_handle_delete(recvHandle);
        }
        recvHandle = nullptr;
        receiverBuffer.reset();
    }

    ASSERT_EQ(bufferMap.size(), 0) << "buffers received is less than the number of buffers sent";

    for (auto handle : allocHandle) {
        native_handle_close(handle);
        native_handle_delete(handle);
    }
    allocHandle.clear();
    senderBuffer.clear();
    timestampUs.clear();
}

// Buffer transfer test between processes.
TEST_F(BufferpoolFunctionalityTest, TransferBuffer) {
    // initialize the receiver
@@ -359,6 +444,94 @@ TEST_F(BufferpoolFunctionalityTest, TransferBuffer) {
            << "received error during buffer transfer\n";
}

/* Validate bufferpool for following corner cases:
 1. invalid connectionID
 2. invalid receiver
 3. when sender is not registered
 4. when connection is closed
*/
// TODO: Enable when the issue in b/212196495 is fixed
TEST_F(BufferpoolFunctionalityTest, DISABLED_ValidityTest) {
    std::vector<uint8_t> vecParams;
    getTestAllocatorParams(&vecParams);

    std::shared_ptr<BufferPoolData> senderBuffer;
    native_handle_t* allocHandle = nullptr;

    // call allocate() on a random connection id
    ConnectionId randomId = rand();
    ResultStatus status = mManager->allocate(randomId, vecParams, &allocHandle, &senderBuffer);
    EXPECT_TRUE(status == ResultStatus::NOT_FOUND);

    // initialize the receiver
    PipeMessage message;
    message.data.command = PipeCommand::INIT;
    sendMessage(mCommandPipeFds, message);
    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
    ASSERT_EQ(message.data.command, PipeCommand::INIT_OK) << "receiver init failed";

    allocHandle = nullptr;
    senderBuffer.reset();
    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);

    ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));

    // send buffers w/o registering sender
    int64_t postUs;
    TransactionId transactionId;

    // random receiver
    status = mManager->postSend(randomId, senderBuffer, &transactionId, &postUs);
    ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on random receiver";

    // establish connection
    android::sp<IClientManager> receiver = IClientManager::getService();
    ASSERT_NE(receiver, nullptr) << "getService failed for receiver\n";

    ConnectionId receiverId;
    status = mManager->registerSender(receiver, mConnectionId, &receiverId);
    ASSERT_EQ(status, ResultStatus::OK)
            << "registerSender failed for connection id " << mConnectionId << "\n";

    allocHandle = nullptr;
    senderBuffer.reset();
    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);
    ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for connection " << mConnectionId;

    ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x88));

    // send the buffer to the receiver
    status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
    ASSERT_EQ(status, ResultStatus::OK) << "postSend failed for receiver " << receiverId << "\n";

    // PipeMessage message;
    message.data.command = PipeCommand::TRANSFER;
    message.data.memsetValue = 0x88;
    message.data.bufferId = senderBuffer->mId;
    message.data.connectionId = receiverId;
    message.data.transactionId = transactionId;
    message.data.timestampUs = postUs;
    sendMessage(mCommandPipeFds, message);
    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
    ASSERT_EQ(message.data.command, PipeCommand::TRANSFER_OK)
            << "received error during buffer transfer\n";

    if (allocHandle) {
        native_handle_close(allocHandle);
        native_handle_delete(allocHandle);
    }

    message.data.command = PipeCommand::STOP;
    sendMessage(mCommandPipeFds, message);
    ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
    ASSERT_EQ(message.data.command, PipeCommand::STOP_OK)
            << "received error during buffer transfer\n";

    // try to send msg to closed connection
    status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
    ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on closed connection";
}

int main(int argc, char** argv) {
    android::hardware::details::setTrebleTestingOverride(true);
    ::testing::InitGoogleTest(&argc, argv);