Merge "BufferQueue: Test remote producer and consumer"

This commit is contained in:
Dan Stoza 2014-03-24 16:17:16 +00:00 committed by Android (Google) Code Review
commit 5cd13e5183
2 changed files with 104 additions and 24 deletions

View File

@ -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;
}

View File

@ -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