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

Commit 5cd13e51 authored by Dan Stoza's avatar Dan Stoza Committed by Android (Google) Code Review
Browse files

Merge "BufferQueue: Test remote producer and consumer"

parents 41d2f807 1a0b8617
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -71,11 +71,11 @@ size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
    size_t c = 0;
    if (mGraphicBuffer != 0) {
        c += mGraphicBuffer->getFlattenedSize();
        FlattenableUtils::align<4>(c);
        c = FlattenableUtils::align<4>(c);
    }
    if (mFence != 0) {
        c += mFence->getFlattenedSize();
        FlattenableUtils::align<4>(c);
        c = FlattenableUtils::align<4>(c);
    }
    return sizeof(int32_t) + c + getPodSize();
}
@@ -91,11 +91,21 @@ size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
    return c;
}

static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
    FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
}

static bool readBoolFromInt(void const*& buffer, size_t& size) {
    int32_t i;
    FlattenableUtils::read(buffer, size, i);
    return static_cast<bool>(i);
}

status_t IGraphicBufferConsumer::BufferItem::flatten(
        void*& buffer, size_t& size, int*& fds, size_t& count) const {

    // make sure we have enough space
    if (count < BufferItem::getFlattenedSize()) {
    if (size < BufferItem::getFlattenedSize()) {
        return NO_MEMORY;
    }

@@ -128,12 +138,12 @@ status_t IGraphicBufferConsumer::BufferItem::flatten(
    FlattenableUtils::write(buffer, size, mTransform);
    FlattenableUtils::write(buffer, size, mScalingMode);
    FlattenableUtils::write(buffer, size, mTimestamp);
    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
    writeBoolAsInt(buffer, size, mIsAutoTimestamp);
    FlattenableUtils::write(buffer, size, mFrameNumber);
    FlattenableUtils::write(buffer, size, mBuf);
    FlattenableUtils::write(buffer, size, mIsDroppable);
    FlattenableUtils::write(buffer, size, mAcquireCalled);
    FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
    writeBoolAsInt(buffer, size, mIsDroppable);
    writeBoolAsInt(buffer, size, mAcquireCalled);
    writeBoolAsInt(buffer, size, mTransformToDisplayInverse);

    return NO_ERROR;
}
@@ -170,12 +180,12 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten(
    FlattenableUtils::read(buffer, size, mTransform);
    FlattenableUtils::read(buffer, size, mScalingMode);
    FlattenableUtils::read(buffer, size, mTimestamp);
    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
    mIsAutoTimestamp = readBoolFromInt(buffer, size);
    FlattenableUtils::read(buffer, size, mFrameNumber);
    FlattenableUtils::read(buffer, size, mBuf);
    FlattenableUtils::read(buffer, size, mIsDroppable);
    FlattenableUtils::read(buffer, size, mAcquireCalled);
    FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
    mIsDroppable = readBoolFromInt(buffer, size);
    mAcquireCalled = readBoolFromInt(buffer, size);
    mTransformToDisplayInverse = readBoolFromInt(buffer, size);

    return NO_ERROR;
}
+83 −13
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@

#include <ui/GraphicBuffer.h>

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <gui/BufferQueue.h>

namespace android {
@@ -32,20 +34,12 @@ namespace android {
class BufferQueueTest : public ::testing::Test {

public:
    static const String16 PRODUCER_NAME;
    static const String16 CONSUMER_NAME;

protected:
    BufferQueueTest() {
        const ::testing::TestInfo* const testInfo =
            ::testing::UnitTest::GetInstance()->current_test_info();
        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
                testInfo->name());

        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
        sp<IServiceManager> serviceManager = defaultServiceManager();
        serviceManager->addService(PRODUCER_NAME, mProducer.get());
        serviceManager->addService(CONSUMER_NAME, mConsumer.get());
    }

    ~BufferQueueTest() {
@@ -62,12 +56,13 @@ protected:
        ASSERT_GE(*bufferCount, 0);
    }

    sp<BnGraphicBufferProducer> mProducer;
    sp<BnGraphicBufferConsumer> mConsumer;
};
    void createBufferQueue() {
        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
    }

const String16 BufferQueueTest::PRODUCER_NAME = String16("BQTestProducer");
const String16 BufferQueueTest::CONSUMER_NAME = String16("BQTestConsumer");
    sp<IGraphicBufferProducer> mProducer;
    sp<IGraphicBufferConsumer> mConsumer;
};

struct DummyConsumer : public BnConsumerListener {
    virtual void onFrameAvailable() {}
@@ -75,7 +70,74 @@ struct DummyConsumer : public BnConsumerListener {
    virtual void onSidebandStreamChanged() {}
};

// XXX: Tests that fork a process to hold the BufferQueue must run before tests
// that use a local BufferQueue, or else Binder will get unhappy
TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
    const String16 PRODUCER_NAME = String16("BQTestProducer");
    const String16 CONSUMER_NAME = String16("BQTestConsumer");

    pid_t forkPid = fork();
    ASSERT_NE(forkPid, -1);

    if (forkPid == 0) {
        // Child process
        sp<BnGraphicBufferProducer> producer;
        sp<BnGraphicBufferConsumer> consumer;
        BufferQueue::createBufferQueue(&producer, &consumer);
        sp<IServiceManager> serviceManager = defaultServiceManager();
        serviceManager->addService(PRODUCER_NAME, producer.get());
        serviceManager->addService(CONSUMER_NAME, consumer.get());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
        LOG_ALWAYS_FATAL("Shouldn't be here");
    }

    sp<IServiceManager> serviceManager = defaultServiceManager();
    sp<IBinder> binderProducer =
        serviceManager->getService(PRODUCER_NAME);
    mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
    EXPECT_TRUE(mProducer != NULL);
    sp<IBinder> binderConsumer =
        serviceManager->getService(CONSUMER_NAME);
    mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
    EXPECT_TRUE(mConsumer != NULL);

    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
    ASSERT_EQ(OK,
            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));

    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;
    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
                    GRALLOC_USAGE_SW_WRITE_OFTEN));
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));

    uint32_t* dataIn;
    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
            reinterpret_cast<void**>(&dataIn)));
    *dataIn = 0x12345678;
    ASSERT_EQ(OK, buffer->unlock());

    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));

    IGraphicBufferConsumer::BufferItem item;
    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));

    uint32_t* dataOut;
    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, 0x12345678);
    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}

TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);
    IGraphicBufferProducer::QueueBufferOutput qbo;
@@ -109,6 +171,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
}

TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);

@@ -125,6 +188,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError)
}

TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);

@@ -139,6 +203,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
}

TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
@@ -187,9 +252,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, 0x12345678);
    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}

TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
@@ -243,9 +310,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, 0x12345678);
    ASSERT_EQ(OK, buffer->unlock());
}

TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
@@ -283,6 +352,7 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, 0x12345678);
    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}

} // namespace android