BQ: Prevent operations on disconnected BQs
- Update unit tests to match
Bug 23763412
Change-Id: I77e59bf6b57b328433c3835450455f80a8fa454b
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 7827072..267c50f 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -117,7 +117,7 @@
//
// The buffer will not be overwritten until the fence signals. The fence
// will usually be the one obtained from dequeueBuffer.
- virtual void cancelBuffer(int slot, const sp<Fence>& fence);
+ virtual status_t cancelBuffer(int slot, const sp<Fence>& fence);
// Query native window attributes. The "what" values are enumerated in
// window.h (e.g. NATIVE_WINDOW_FORMAT).
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 5b84bdc..6885eb0 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -74,7 +74,8 @@
// The slot must be in the range of [0, NUM_BUFFER_SLOTS).
//
// Return of a value other than NO_ERROR means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - one of the two conditions occurred:
// * slot was out of range (see above)
// * buffer specified by the slot is not dequeued
@@ -170,7 +171,8 @@
// success.
//
// Return of a negative means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - both in async mode and buffer count was less than the
// max numbers of buffers that can be allocated at once.
// * INVALID_OPERATION - cannot attach the buffer because it would cause
@@ -198,7 +200,8 @@
// requestBuffer).
//
// Return of a value other than NO_ERROR means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - the given slot number is invalid, either because it is
// out of the range [0, NUM_BUFFER_SLOTS), or because the slot
// it refers to is not currently dequeued and requested.
@@ -218,7 +221,8 @@
// equivalent to fence from the dequeueBuffer call.
//
// Return of a value other than NO_ERROR means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - either outBuffer or outFence were NULL.
// * NO_MEMORY - no slots were found that were both free and contained a
// GraphicBuffer.
@@ -237,7 +241,8 @@
// success.
//
// Return of a negative value means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - outSlot or buffer were NULL, invalid combination of
// async mode and buffer count override, or the generation
// number of the buffer did not match the buffer queue.
@@ -271,7 +276,8 @@
// (refer to the documentation below).
//
// Return of a value other than NO_ERROR means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned.
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
// * BAD_VALUE - one of the below conditions occurred:
// * fence was NULL
// * scaling mode was unknown
@@ -384,9 +390,19 @@
//
// The buffer is not queued for use by the consumer.
//
+ // The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+ //
// The buffer will not be overwritten until the fence signals. The fence
// will usually be the one obtained from dequeueBuffer.
- virtual void cancelBuffer(int slot, const sp<Fence>& fence) = 0;
+ //
+ // Return of a value other than NO_ERROR means an error has occurred:
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
+ // * BAD_VALUE - one of the below conditions occurred:
+ // * fence was NULL
+ // * slot index was out of range (see above).
+ // * the slot was not in the dequeued state
+ virtual status_t cancelBuffer(int slot, const sp<Fence>& fence) = 0;
// query retrieves some information for this surface
// 'what' tokens allowed are that of NATIVE_WINDOW_* in <window.h>
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 8cc0cfa..06cdeab 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -57,6 +57,11 @@
return NO_INIT;
}
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("requestBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
+
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
@@ -286,6 +291,16 @@
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mConsumerName = mCore->mConsumerName;
+
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
+ }
+
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
} // Autolock scope
BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
@@ -453,6 +468,11 @@
return NO_INIT;
}
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("detachBuffer(P): BufferQueue has no connected producer");
+ return NO_INIT;
+ }
+
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)",
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
@@ -487,13 +507,19 @@
}
Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
if (mCore->mIsAbandoned) {
BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
return NO_INIT;
}
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
+
+ mCore->waitWhileAllocatingLocked();
+
if (mCore->mFreeBuffers.empty()) {
return NO_MEMORY;
}
@@ -524,7 +550,16 @@
}
Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
+
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("attachBuffer(P): BufferQueue has been abandoned");
+ return NO_INIT;
+ }
+
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("attachBuffer(P): BufferQueue has no connected producer");
+ return NO_INIT;
+ }
if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
@@ -533,6 +568,8 @@
return BAD_VALUE;
}
+ mCore->waitWhileAllocatingLocked();
+
status_t returnFlags = NO_ERROR;
int found;
// TODO: Should we provide an async flag to attachBuffer? It seems
@@ -612,6 +649,11 @@
return NO_INIT;
}
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
+
const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
if (slot < 0 || slot >= maxBufferCount) {
@@ -748,27 +790,32 @@
return NO_ERROR;
}
-void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
+status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
ATRACE_CALL();
BQ_LOGV("cancelBuffer: slot %d", slot);
Mutex::Autolock lock(mCore->mMutex);
if (mCore->mIsAbandoned) {
BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
- return;
+ return NO_INIT;
+ }
+
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
}
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return;
+ return BAD_VALUE;
} else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
"(state = %d)", slot, mSlots[slot].mBufferState);
- return;
+ return BAD_VALUE;
} else if (fence == NULL) {
BQ_LOGE("cancelBuffer: fence is NULL");
- return;
+ return BAD_VALUE;
}
mCore->mFreeBuffers.push_front(slot);
@@ -776,6 +823,8 @@
mSlots[slot].mFence = fence;
mCore->mDequeueCondition.broadcast();
mCore->validateConsistencyLocked();
+
+ return NO_ERROR;
}
int BufferQueueProducer::query(int what, int *outValue) {
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 6495aa9..3cdcd79 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -206,12 +206,17 @@
return result;
}
- virtual void cancelBuffer(int buf, const sp<Fence>& fence) {
+ virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
data.writeInt32(buf);
data.write(*fence.get());
- remote()->transact(CANCEL_BUFFER, data, &reply);
+ status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
+ return result;
}
virtual int query(int what, int* value) {
@@ -434,7 +439,8 @@
int buf = data.readInt32();
sp<Fence> fence = new Fence();
data.read(*fence.get());
- cancelBuffer(buf, fence);
+ status_t result = cancelBuffer(buf, fence);
+ reply->writeInt32(result);
return NO_ERROR;
}
case QUERY: {
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index d559e54..289cc74 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -449,6 +449,9 @@
const CpuConsumerTestParams& params,
int maxBufferSlack) {
status_t err;
+ err = native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU);
+ ASSERT_NO_ERROR(err, "connect error: ");
+
err = native_window_set_buffers_dimensions(anw.get(),
params.width, params.height);
ASSERT_NO_ERROR(err, "set_buffers_dimensions error: ");
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index d6bd8a8..34fb998 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -208,6 +208,27 @@
return mProducer->dequeueBuffer(&result->slot, &result->fence, async, w, h, format, usage);
}
+ void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence,
+ sp<GraphicBuffer> *buffer)
+ {
+ ASSERT_TRUE(slot != NULL);
+ ASSERT_TRUE(fence != NULL);
+ ASSERT_TRUE(buffer != NULL);
+
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(slot, fence,
+ QUEUE_BUFFER_INPUT_ASYNC, DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS)));
+
+ EXPECT_LE(0, *slot);
+ EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot);
+
+ // Request the buffer (pre-requisite for queueing)
+ ASSERT_OK(mProducer->requestBuffer(*slot, buffer));
+ }
+
private: // hide from test body
sp<DummyConsumer> mDC;
@@ -334,12 +355,11 @@
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- // XX: OK to assume first call returns this flag or not? Not really documented.
- ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS));
+ TEST_PRODUCER_USAGE_BITS)));
EXPECT_LE(0, dequeuedSlot);
EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
@@ -400,11 +420,11 @@
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS));
+ TEST_PRODUCER_USAGE_BITS)));
// Slot was enqueued without requesting a buffer
{
@@ -470,11 +490,11 @@
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS));
+ TEST_PRODUCER_USAGE_BITS)));
// No return code, but at least test that it doesn't blow up...
// TODO: add a return code
@@ -482,6 +502,7 @@
}
TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
int minUndequeuedBuffers;
ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
&minUndequeuedBuffers));
@@ -499,10 +520,10 @@
for (int i = 0; i < minBuffers; ++i) {
DequeueBufferResult result;
- EXPECT_LE(OK,
- dequeueBuffer(QUEUE_BUFFER_INPUT_ASYNC,
+ EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (dequeueBuffer(QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS, &result))
+ TEST_PRODUCER_USAGE_BITS, &result)))
<< "iteration: " << i << ", slot: " << result.slot;
dequeueList.push_back(result);
@@ -520,17 +541,18 @@
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- EXPECT_LE(OK,
- mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT,
DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS))
+ TEST_PRODUCER_USAGE_BITS)))
<< "iteration: " << i << ", slot: " << dequeuedSlot;
}
}
TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) {
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
int minUndequeuedBuffers;
ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
&minUndequeuedBuffers));
@@ -550,12 +572,12 @@
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- ASSERT_LE(OK,
- mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC,
DEFAULT_WIDTH, DEFAULT_HEIGHT,
DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS))
+ TEST_PRODUCER_USAGE_BITS)))
<< "slot: " << dequeuedSlot;
}
@@ -574,6 +596,7 @@
TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1;
@@ -589,9 +612,10 @@
// Should now be able to queue/dequeue as many buffers as we want without
// blocking
for (int i = 0; i < 5; ++i) {
- ASSERT_LE(OK, mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
true, DEFAULT_WIDTH, DEFAULT_HEIGHT,
- DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS)) << "slot : "
+ DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS))) << "slot : "
<< dequeuedSlot;
ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
@@ -599,14 +623,16 @@
}
TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Fails) {
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
// Prerequisite to fail out a valid setBufferCount call
{
int dequeuedSlot = -1;
sp<Fence> dequeuedFence;
- ASSERT_LE(OK, mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
QUEUE_BUFFER_INPUT_ASYNC, DEFAULT_WIDTH, DEFAULT_HEIGHT,
- DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS)) << "slot: "
+ DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS))) << "slot: "
<< dequeuedSlot;
}
@@ -622,4 +648,103 @@
<< false;
}
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_dequeueBuffer) {
+ int slot = -1;
+ sp<Fence> fence;
+
+ ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence,
+ QUEUE_BUFFER_INPUT_ASYNC, DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS));
+}
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_detachNextBuffer) {
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+
+ ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence));
+}
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_requestBuffer) {
+ ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+ int slot = -1;
+ sp<Fence> fence;
+
+ ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
+ (mProducer->dequeueBuffer(&slot, &fence,
+ QUEUE_BUFFER_INPUT_ASYNC, DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS)));
+
+ EXPECT_LE(0, slot);
+ EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot);
+
+ ASSERT_OK(mProducer->disconnect(TEST_API));
+
+ sp<GraphicBuffer> buffer;
+
+ ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
+}
+
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_detachBuffer) {
+ int slot = -1;
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+
+ setupDequeueRequestBuffer(&slot, &fence, &buffer);
+
+ ASSERT_OK(mProducer->disconnect(TEST_API));
+
+ ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot));
+}
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_queueBuffer) {
+ int slot = -1;
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+
+ setupDequeueRequestBuffer(&slot, &fence, &buffer);
+
+ ASSERT_OK(mProducer->disconnect(TEST_API));
+
+ // A generic "valid" input
+ IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+ IGraphicBufferProducer::QueueBufferOutput output;
+
+ ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
+}
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_cancelBuffer) {
+ int slot = -1;
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+
+ setupDequeueRequestBuffer(&slot, &fence, &buffer);
+
+ ASSERT_OK(mProducer->disconnect(TEST_API));
+
+ ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence));
+}
+
+TEST_F(IGraphicBufferProducerTest,
+ DisconnectedProducerReturnsError_attachBuffer) {
+ int slot = -1;
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+
+ setupDequeueRequestBuffer(&slot, &fence, &buffer);
+
+ ASSERT_OK(mProducer->detachBuffer(slot));
+
+ ASSERT_OK(mProducer->disconnect(TEST_API));
+
+ ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
+}
+
} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index c61eb1a..2356f54 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -216,6 +216,7 @@
}
TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(1, buf->width);
@@ -225,6 +226,7 @@
}
TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
@@ -236,6 +238,7 @@
}
TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
@@ -247,6 +250,7 @@
}
TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
@@ -258,6 +262,7 @@
}
TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
@@ -276,6 +281,7 @@
}
TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
@@ -293,6 +299,7 @@
}
TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
sp<GLConsumer> st(mST);
ANativeWindowBuffer* buf;
EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
@@ -305,6 +312,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
ANativeWindowBuffer* buf[2];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
@@ -325,6 +333,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
ANativeWindowBuffer* buf[2];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
@@ -351,6 +360,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 0));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
@@ -374,6 +384,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
@@ -394,6 +405,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
@@ -414,8 +426,8 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
-
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
EXPECT_EQ(OK, mST->updateTexImage());
@@ -439,6 +451,7 @@
TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
android_native_buffer_t* buf[3];
android_native_buffer_t* firstBuf;
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &firstBuf));
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf, -1));
@@ -458,6 +471,7 @@
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
// We should be able to dequeue all the buffers before we've queued mANWy.
@@ -483,6 +497,7 @@
}
TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
android_native_rect_t rect = {-2, -13, 40, 18};
native_window_set_crop(mANW.get(), &rect);
@@ -537,6 +552,7 @@
};
android_native_buffer_t* buf[3];
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
// dequeue/queue/update so we have a current buffer
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
@@ -560,6 +576,7 @@
TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
android_native_buffer_t* buf[3];
float mtx[16] = {};
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
@@ -590,6 +607,7 @@
TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
android_native_buffer_t* buf[3];
float mtx[16] = {};
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
@@ -639,6 +657,7 @@
crop.right = 5;
crop.bottom = 5;
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 8));
ASSERT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp
index c243fc0..0606839 100644
--- a/libs/gui/tests/SurfaceTextureFBO_test.cpp
+++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp
@@ -27,6 +27,8 @@
const int texWidth = 64;
const int texHeight = 64;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index 0e85b90..1a904b5 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -28,6 +28,8 @@
const int texWidth = 64;
const int texHeight = 66;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -76,6 +78,8 @@
const int texWidth = 64;
const int texHeight = 64;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -124,6 +128,8 @@
const int texWidth = 64;
const int texHeight = 66;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -190,6 +196,8 @@
enum { texHeight = 16 };
enum { numFrames = 1024 };
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -333,6 +341,8 @@
const int texWidth = 64;
const int texHeight = 66;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -377,6 +387,8 @@
const int texWidth = 64;
const int texHeight = 64;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -435,7 +447,10 @@
virtual bool threadLoop() {
ANativeWindowBuffer* anb;
- native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
+ if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
+ NO_ERROR) {
+ return false;
+ }
for (int numFrames =0 ; numFrames < 2; numFrames ++) {
@@ -452,7 +467,10 @@
}
}
- native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
+ if (native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU)
+ != NO_ERROR) {
+ return false;
+ }
return false;
}
@@ -486,7 +504,7 @@
// attempt to release a buffer that it does not owned
TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
- NATIVE_WINDOW_API_EGL));
+ NATIVE_WINDOW_API_CPU));
ANativeWindowBuffer *anb;
@@ -500,9 +518,9 @@
EXPECT_EQ(OK,mST->updateTexImage());
ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
- NATIVE_WINDOW_API_EGL));
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
- NATIVE_WINDOW_API_EGL));
+ NATIVE_WINDOW_API_CPU));
EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
@@ -512,7 +530,7 @@
EXPECT_EQ(OK,mST->updateTexImage());
ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
- NATIVE_WINDOW_API_EGL));
+ NATIVE_WINDOW_API_CPU));
}
TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
@@ -614,6 +632,11 @@
Mutex::Autolock lock(mMutex);
ANativeWindowBuffer* anb;
+ if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
+ NO_ERROR) {
+ return false;
+ }
+
// Frame 1
if (native_window_dequeue_buffer_and_wait(mANW.get(),
&anb) != NO_ERROR) {
@@ -678,6 +701,9 @@
int texHeight = 16;
ANativeWindowBuffer* anb;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
+ NATIVE_WINDOW_API_CPU));
+
GLint maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
diff --git a/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
index f74ac3d..5b02dcf 100644
--- a/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
@@ -26,6 +26,7 @@
namespace android {
TEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -40,6 +41,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -55,6 +57,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
DetachFromContextSucceedsAfterProducerDisconnect) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -70,6 +73,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -82,6 +86,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -96,6 +101,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -112,6 +118,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -128,6 +135,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Detach from the primary context.
@@ -139,6 +147,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -169,6 +178,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachToContextSucceedsAfterProducerDisconnect) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -200,6 +210,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachToContextSucceedsBeforeUpdateTexImage) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Detach from the primary context.
@@ -230,6 +241,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -247,6 +259,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -259,6 +272,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Attempt to attach to the primary context.
@@ -266,6 +280,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -285,6 +300,7 @@
}
TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Latch the texture contents on the primary context.
@@ -323,6 +339,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
// Detach from the primary context.
@@ -361,6 +378,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
// produce two frames and consume them both on the primary context
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
@@ -387,6 +405,7 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachAfterDisplayTerminatedSucceeds) {
+ ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
// produce two frames and consume them both on the primary context
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 3f495f8..6f0104a 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -100,6 +100,8 @@
ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(),
64, 64, 0, 0x7fffffff, false));
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
+ NATIVE_WINDOW_API_CPU));
// Set the PROTECTED usage bit and verify that the screenshot fails. Note
// that we need to dequeue a buffer in order for it to actually get
// allocated in SurfaceFlinger.
@@ -190,6 +192,8 @@
// Allocate a buffer with a generation number of 0
ANativeWindowBuffer* buffer;
int fenceFd;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(window.get(),
+ NATIVE_WINDOW_API_CPU));
ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fenceFd));
ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fenceFd));
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 94f30d5..0880a44 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -476,7 +476,8 @@
return NO_ERROR;
}
-void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
+status_t VirtualDisplaySurface::cancelBuffer(int pslot,
+ const sp<Fence>& fence) {
if (mDisplayId < 0)
return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 5807eb1..91e94f1 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -108,7 +108,7 @@
virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
virtual status_t queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output);
- virtual void cancelBuffer(int pslot, const sp<Fence>& fence);
+ virtual status_t cancelBuffer(int pslot, const sp<Fence>& fence);
virtual int query(int what, int* value);
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output);
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index 85182d9..f16ad59 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -89,8 +89,8 @@
return mProducer->queueBuffer(slot, input, output);
}
-void MonitoredProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
- mProducer->cancelBuffer(slot, fence);
+status_t MonitoredProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
+ return mProducer->cancelBuffer(slot, fence);
}
int MonitoredProducer::query(int what, int* value) {
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index f5575ff..0bdc050 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -46,7 +46,7 @@
const sp<GraphicBuffer>& buffer);
virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
QueueBufferOutput* output);
- virtual void cancelBuffer(int slot, const sp<Fence>& fence);
+ virtual status_t cancelBuffer(int slot, const sp<Fence>& fence);
virtual int query(int what, int* value);
virtual status_t connect(const sp<IProducerListener>& token, int api,
bool producerControlledByApp, QueueBufferOutput* output);